![Scikit-learn kütüphanesinin sınıflandırma modelleri ve bunların ONNX'e aktarılması](https://c.mql5.com/2/58/Scikit_learn_to-ONNX_600x314.jpg)
Scikit-learn kütüphanesinin sınıflandırma modelleri ve bunların ONNX'e aktarılması
Teknolojinin gelişmesi, veri işleme algoritmaları oluşturmaya yönelik temelde yeni bir yaklaşımın ortaya çıkmasına neden olmuştur. Önceden, her bir özel görevi çözmek için, ilgili algoritmaların açık bir şekilde biçimlendirilmesi ve geliştirilmesi gerekiyordu.
Makine öğreniminde bilgisayar, verileri işlemenin en iyi yollarını kendi kendine bulmayı öğrenir. Makine öğrenimi modelleri, sınıflandırma görevlerini (sabit bir sınıf kümesinin olduğu ve amacın her bir sınıfa ait belirli bir özellik kümesinin olasılıklarını bulmak olduğu) ve regresyon görevlerini (amacın belirli bir özellik kümesine dayalı olarak hedef değişkenin sayısal değerini hesaplamak olduğu) başarıyla çözebilir. Bu temel bileşenlere dayanarak daha karmaşık veri işleme modelleri oluşturulabilir.
Scikit-learn kütüphanesi hem sınıflandırma hem de regresyon için çok sayıda araç sağlar. Belirli yöntemlerin ve modellerin seçimi verilerin karakteristiğine bağlıdır, çünkü farklı yöntemler göreve bağlı olarak değişen etkinliğe sahip olabilir ve farklı sonuçlar sağlayabilir.
“ONNX Runtime is now open source” başlıklı basın bülteninde, ONNX Runtime'ın ONNX-ML profilini de desteklediği belirtilmektedir:
ONNX-ML profili, ONNX'in makine öğrenimi (ML) modelleri için özel olarak tasarlanmış bir parçasıdır. Sınıflandırma, regresyon, kümeleme vb. gibi çeşitli ML model türlerini, ONNX'i destekleyen çeşitli platformlarda ve ortamlarda kullanılabilecek uygun bir biçimde tanımlamak ve temsil etmek için tasarlanmıştır. ONNX-ML profili, makine öğrenimi modellerinin iletimini, dağıtımını ve yürütülmesini basitleştirerek onları daha erişilebilir ve taşınabilir hale getirir.
Bu makalede, Fisher'ın iris sınıflandırma görevini çözmek için Scikit-learn paketindeki tüm sınıflandırma modellerinin uygulanmasını inceleyeceğiz. Ayrıca bu modelleri ONNX formatına dönüştürmeye ve elde edilen modelleri MQL5 programlarında kullanmaya çalışacağız.
Ek olarak, orijinal modellerin doğruluğunu tam iris veri setindeki ONNX versiyonlarıyla karşılaştıracağız.
İçindekiler
- 1. Fisher'ın iris veri kümesi
- 2. Sınıflandırma için modeller
Scikit-learn sınıflandırıcılarının listesi
Modellerde farklı çıktı temsilleri iris.mqh - 2.1. SVC Classifier
2.1.1. SVC Classifier modelini oluşturmak için kod
2.1.2. SVC Classifier modeliyle çalışmak için MQL5 kodu
2.1.3. SVC Classifier modelinin ONNX gösterimi - 2.2. LinearSVC Classifier
2.2.1. LinearSVC Classifier modelini oluşturmak için kod
2.2.2. LinearSVC Classifier modeliyle çalışmak için MQL5 kodu
2.2.3. LinearSVC Classifier modelinin ONNX gösterimi - 2.3. NuSVC Classifier
2.3.1. NuSVC Classifier modelini oluşturmak için kod
2.3.2. NuSVC Classifier modeliyle çalışmak için MQL5 kodu
2.3.3. NuSVC Classifier modelinin ONNX gösterimi - 2.4. Radius Neighbors Classifier
2.4.1. Radius Neighbors Classifier modelini oluşturmak için kod
2.4.2. Radius Neighbors Classifier modeliyle çalışmak için MQL5 kodu
2.4.3. Radius Neighbors Classifier modelinin ONNX gösterimi - 2.5. Ridge Classifier
2.5.1. Ridge Classifier modelini oluşturmak için kod
2.5.2. Ridge Classifier modeliyle çalışmak için MQL5 kodu
2.5.3. Ridge Classifier modelinin ONNX gösterimi - 2.6. Ridge ClassifierCV
2.6.1. Ridge ClassifierCV modelini oluşturmak için kod
2.6.2. Ridge ClassifierCV modeliyle çalışmak için MQL5 kodu
2.6.3. Ridge ClassifierCV modelinin ONNX gösterimi - 2.7. Random Forest Classifier
2.7.1. Random Forest Classifier modelini oluşturmak için kod
2.7.2. Random Forest Classifier modeliyle çalışmak için MQL5 kodu
2.7.3. Random Forest Classifier modelinin ONNX gösterimi - 2.8. Gradient Boosting Classifier
2.8.1. Gradient Boosting Classifier modelini oluşturmak için kod
2.8.2. Gradient Boosting Classifier modeliyle çalışmak için MQL5 kodu
2.8.3. Gradient Boosting Classifier modelinin ONNX gösterimi - 2.9. Adaptive Boosting Classifier
2.9.1. Adaptive Boosting Classifier modelini oluşturmak için kod
2.9.2. Adaptive Boosting Classifier modeliyle çalışmak için MQL5 kodu
2.9.3. Adaptive Boosting Classifier modelinin ONNX gösterimi - 2.10. Bootstrap Aggregating Classifier
2.10.1. Bootstrap Aggregating Classifier modelini oluşturmak için kod
2.10.2. Bootstrap Aggregating Classifier modeliyle çalışmak için MQL5 kodu
2.10.3. Bootstrap Aggregating Classifier modelinin ONNX gösterimi - 2.11. K-Nearest Neighbors (K-NN) Classifier
2.11.1. K-Nearest Neighbors (K-NN) Classifier modelini oluşturmak için kod
2.11.2. K-Nearest Neighbors (K-NN) Classifier modeliyle çalışmak için MQL5 kodu
2.11.3. K-Nearest Neighbors (K-NN) Classifier modelinin ONNX gösterimi - 2.12. Decision Tree Classifier
2.12.1. Decision Tree Classifier modelini oluşturmak için kod
2.12.2. Decision Tree Classifier modeliyle çalışmak için MQL5 kodu
2.12.3. Decision Tree Classifier modelinin ONNX gösterimi - 2.13. Logistic Regression Classifier
2.13.1. Logistic Regression Classifier modelini oluşturmak için kod
2.13.2. Logistic Regression Classifier modeliyle çalışmak için MQL5 kodu
2.13.3. Logistic Regression Classifier modelinin ONNX gösterimi - 2.14. LogisticRegressionCV Classifier
2.14.1. LogisticRegressionCV Classifier modelini oluşturmak için kod
2.14.2. LogisticRegressionCV Classifier modeliyle çalışmak için MQL5 kodu
2.14.3. LogisticRegressionCV Classifier modelinin ONNX gösterimi - 2.15. Passive-Aggressive (PA) Classifier
2.15.1. Passive-Aggressive (PA) Classifier modelini oluşturmak için kod
2.15.2. Passive-Aggressive (PA) Classifier modeliyle çalışmak için MQL5 kodu
2.15.3. Passive-Aggressive (PA) Classifier modelinin ONNX gösterimi - 2.16. Perceptron Classifier
2.16.1. Perceptron Classifier modelini oluşturmak için kod
2.16.2. Perceptron Classifier modeliyle çalışmak için MQL5 kodu
2.16.3. Perceptron Classifier modelinin ONNX gösterimi - 2.17. Stochastic Gradient Descent Classifier
2.17.1. Stochastic Gradient Descent Classifier modelini oluşturmak için kod
2.17.2. Stochastic Gradient Descent Classifier modeliyle çalışmak için MQL5 kodu
2.17.3. Stochastic Gradient Descent Classifier modelinin ONNX gösterimi - 2.18. Gaussian Naive Bayes (GNB) Classifier
2.18.1. Gaussian Naive Bayes (GNB) Classifier modelini oluşturmak için kod
2.18.2. Gaussian Naive Bayes (GNB) Classifier modeliyle çalışmak için MQL5 kodu
2.18.3. Gaussian Naive Bayes (GNB) Classifier modelinin ONNX gösterimi - 2.19. Multinomial Naive Bayes (MNB) Classifier
2.19.1. Multinomial Naive Bayes (MNB) Classifier modelini oluşturmak için kod
2.19.2. Multinomial Naive Bayes (MNB) Classifier modeliyle çalışmak için MQL5 kodu
2.19.3. Multinomial Naive Bayes (MNB) Classifier modelinin ONNX gösterimi - 2.20. Complement Naive Bayes (CNB) Classifier
2.20.1. Complement Naive Bayes (CNB) Classifier modelini oluşturmak için kod
2.20.2. Complement Naive Bayes (CNB) Classifier modeliyle çalışmak için MQL5 kodu
2.20.3. Complement Naive Bayes (CNB) Classifier modelinin ONNX gösterimi - 2.21. Bernoulli Naive Bayes (BNB) Classifier
2.21.1. Bernoulli Naive Bayes (BNB) Classifier modelini oluşturmak için kod
2.21.2. Bernoulli Naive Bayes (BNB) Classifier modeliyle çalışmak için MQL5 kodu
2.21.3. Bernoulli Naive Bayes (BNB) Classifier modelinin ONNX gösterimi - 2.22. Multilayer Perceptron Classifier
2.22.1. Multilayer Perceptron Classifier modelini oluşturmak için kod
2.22.2. Multilayer Perceptron Classifier modeliyle çalışmak için MQL5 kodu
2.22.3. Multilayer Perceptron Classifier modelinin ONNX gösterimi - 2.23. Linear Discriminant Analysis (LDA) Classifier
2.23.1. Linear Discriminant Analysis (LDA) Classifier modelini oluşturmak için kod
2.23.2. Linear Discriminant Analysis (LDA) Classifier modeliyle çalışmak için MQL5 kodu
2.23.3. Linear Discriminant Analysis (LDA) Classifier modelinin ONNX gösterimi - 2.24. Hist Gradient Boosting
2.24.1. Histogram-Based Gradient Boosting Classifier modelini oluşturmak için kod
2.24.2. Histogram-Based Gradient Boosting Classifier modeliyle çalışmak için MQL5 kodu
2.24.3. Histogram-Based Gradient Boosting Classifier modelinin ONNX gösterimi - 2.25. CategoricalNB Classifier
2.25.1. CategoricalNB Classifier modelini oluşturmak için kod
2.25.2. CategoricalNB Classifier modeliyle çalışmak için MQL5 kodu
2.25.3. CategoricalNB Classifier modelinin ONNX gösterimi - 2.26. ExtraTreeClassifier
2.26.1. ExtraTreeClassifier modelini oluşturmak için kod
2.26.2. ExtraTreeClassifier modeliyle çalışmak için MQL5 kodu
2.26.3. ExtraTreeClassifier modelinin ONNX gösterimi - 2.27. ExtraTreesClassifier
2.27.1. ExtraTreesClassifier modelini oluşturmak için kod
2.27.2. ExtraTreesClassifier modeliyle çalışmak için MQL5 kodu
2.27.3. ExtraTreesClassifier modelinin ONNX gösterimi - 2.28. Tüm modellerin doğruluğunun karşılaştırılması
2.28.1. Tüm modelleri hesaplamak ve bir doğruluk karşılaştırma grafiği oluşturmak için kod
2.28.2. Tüm ONNX modellerini çalıştırmak için MQL5 kodu - 2.29. ONNX'e dönüştürülemeyen Scikit-learn sınıflandırma modelleri
- 2.29.1. DummyClassifier
2.29.1.1. DummyClassifier modelini oluşturmak için kod - 2.29.2. GaussianProcessClassifier
2.29.2.1. GaussianProcessClassifier modelini oluşturmak için kod - 2.29.3. LabelPropagation Classifier
2.29.3.1. LabelPropagation Classifier modelini oluşturmak için kod - 2.29.4. LabelSpreading Classifier
2.29.4.1. LabelSpreading Classifier modelini oluşturmak için kod - 2.29.5. NearestCentroid Classifier
2.29.5.1. NearestCentroid Classifier modelini oluşturmak için kod - 2.29.6. Quadratic Discriminant Analysis Classifier
2.29.6.1. Quadratic Discriminant Analysis Classifier modelini oluşturmak için kod - Sonuç
1. Fisher'ın iris veri kümesi
İris veri kümesi, makine öğrenimi alanında en iyi bilinen ve en yaygın kullanılan veri kümelerinden biridir. İlk olarak 1936 yılında istatistikçi ve biyolog R.A. Fisher tarafından tanıtılmış ve o zamandan beri sınıflandırma görevleri için klasik bir veri kümesi haline gelmiştir.
İris veri kümesi, üç iris çiçeği türünün (Iris setosa, Iris virginica ve Iris versicolor) çanak ve taç yapraklarının ölçümlerinden oluşur.
Şekil 1. Iris setosa
Şekil 2. Iris virginica
Şekil 3. Iris versicolor
İris veri kümesi, her üç türden 50'şer örnek olmak üzere 150 iris çiçeği örneğinden oluşmaktadır. Her örnek dört sayısal özelliğe sahiptir (santimetre cinsinden ölçülür):
- Çanak yaprak uzunluğu (sepal length)
- Çanak yaprak genişliği (sepal width)
- Taç yaprak uzunluğu (petal length)
- Taç yaprak genişliği (petal width)
Her örnek ayrıca iris çiçeği türünü (Iris setosa, Iris virginica veya Iris versicolor) belirten ilgili bir sınıfa sahiptir. Bu sınıflandırma özelliği, iris veri kümesini sınıflandırma ve kümeleme gibi makine öğrenimi görevleri için ideal bir veri kümesi haline getirmektedir.
MetaEditor Python komut dosyalarıyla çalışmaya olanak tanır. Bir Python komut dosyası oluşturmak için MetaEditor'da "Dosya" menüsünden "Yeni"ye tıklayın ve böylece oluşturulacak nesneyi seçmek için bir iletişim kutusu görünecektir (bkz. Şekil 4).
Şekil 4. MQL5 Sihirbazında Python komut dosyası oluşturma - Adım 1
Ardından, komut dosyası için bir ad girin, örneğin "IRIS.py" (bkz. Şekil 5).
Şekil 5. MQL5 Sihirbazında Python komut dosyası oluşturma - Adım 2 - Komut dosyası adı
Devamında, hangi kütüphanelerin kullanılacağını belirtebilirsiniz. Bizim durumumuzda, bu alanları boş bırakacağız (bkz. Şekil 6).
Şekil 6. MQL5 Sihirbazında Python komut dosyası oluşturma - Adım 3
İris veri setini analiz etmeye başlamanın bir yolu da verileri görselleştirmektir. Grafiksel bir gösterim, verilerin yapısını ve özellikler arasındaki ilişkileri daha iyi anlamamızı sağlar.
Örneğin, farklı iris çiçeği türlerinin özellik uzayında nasıl dağıldığını görmek için bir dağılım grafiği oluşturabilirsiniz.
Python komut dosyası kodu:
# The script shows the scatter plot of the Iris dataset features # Copyright 2023, MetaQuotes Ltd. # https://mql5.com import matplotlib.pyplot as plt from sklearn import datasets # load the Iris dataset iris = datasets.load_iris() X = iris.data y = iris.target # extract sepal length and sepal width (the first two features) sepal_length = X[:, 0] sepal_width = X[:, 1] # create a scatter plot plt.figure(figsize=(8, 6)) plt.scatter(sepal_length, sepal_width, c=y, cmap=plt.cm.Set1, edgecolor='k') plt.xlabel('Sepal Length (cm)') plt.ylabel('Sepal Width (cm)') plt.title('Scatter Plot for Sepal Length and Sepal Width') plt.colorbar(label='Iris Species', ticks=[0, 1, 2]) plt.show() # save the scatter plot to a file (optional) # plt.savefig('scatter_plot_sepal_length_width.png') # Extract petal length and petal width (the third and fourth features) petal_length = X[:, 2] petal_width = X[:, 3] # create a scatter plot plt.figure(figsize=(8, 6)) plt.scatter(petal_length, petal_width, c=y, cmap=plt.cm.Set1, edgecolor='k') plt.xlabel('Petal Length (cm)') plt.ylabel('Petal Width (cm)') plt.title('Scatter Plot for Petal Length and Petal Width') plt.colorbar(label='Iris Species', ticks=[0, 1, 2]) plt.show() # save the scatter plot to a file (optional) # plt.savefig('scatter_plot_petal_length_width.png')
Bu kodu çalıştırmak için MetaEditor'a kopyalamanız (bkz. Şekil 7) ve "Derle"ye tıklamanız gerekir.
Şekil 7. MetaEditor'da IRIS.py komut dosyası
Sonrasında, grafikler ekranda görünecektir:
Şekil 8. Çanak yaprak uzunluğu/çanak yaprak genişliği grafiği ile MetaEditor'da IRIS.py komut dosyası
Şekil 9. Şekil 9. Taç yaprak uzunluğu/taç yaprak genişliği grafiği ile MetaEditor'da IRIS.py komut dosyası
Onlara daha yakından bakalım.
Şekil 10. Çanak yaprak uzunluğu/çanak yaprak genişliği dağılım grafiği
Bu grafikte, farklı iris çiçeği türlerinin çanak yaprak uzunluğu ve çanak yaprak genişliğine göre nasıl dağıldığını görüyoruz. Iris setosa'nın diğer iki türe kıyasla tipik olarak daha kısa ve daha geniş çanak yapraklara sahip olduğunu gözlemliyoruz.
Şekil 11. Taç yaprak uzunluğu/taç yaprak genişliği dağılım grafiği
Bu grafikte, farklı iris çiçeği türlerinin taç yaprak uzunluğu ve taç yaprak genişliğine göre nasıl dağıldığını görüyoruz. Iris setosa'nın en kısa ve en dar taç yapraklara, Iris virginica'nın en uzun ve en geniş taç yapraklara sahip olduğunu ve Iris versicolor'un bu ikisinin arasında kaldığını gözlemliyoruz.
İris veri kümesi, makine öğrenimi modellerini eğitmek ve test etmek için ideal bir veri kümesidir. Bunu, bir sınıflandırma görevi için makine öğrenimi modellerinin etkinliğini analiz etmek için kullanacağız.
2. Sınıflandırma için modeller
Sınıflandırma, makine öğrenimindeki temel görevlerden biridir ve amacı, verileri belirli özelliklere göre farklı kategorilere veya sınıflara ayırmaktır.
Şimdi scikit-learn paketindeki ana makine öğrenimi modellerini inceleyelim.
Scikit-learn sınıflandırıcılarının listesi
Scikit-learn'deki mevcut sınıflandırıcıların listesini görüntülemek için aşağıdaki kodu kullanabilirsiniz:
# ScikitLearnClassifiers.py # The script lists all the classification algorithms available in scikit-learn # Copyright 2023, MetaQuotes Ltd. # https://mql5.com # print Python version from platform import python_version print("The Python version is ", python_version()) # print scikit-learn version import sklearn print('The scikit-learn version is {}.'.format(sklearn.__version__)) # print scikit-learn classifiers from sklearn.utils import all_estimators classifiers = all_estimators(type_filter='classifier') for index, (name, ClassifierClass) in enumerate(classifiers, start=1): print(f"Classifier {index}: {name}")
Çıktı:
Python The scikit-learn version is 1.2.2.
Python Classifier 1: AdaBoostClassifier
Python Classifier 2: BaggingClassifier
Python Classifier 3: BernoulliNB
Python Classifier 4: CalibratedClassifierCV
Python Classifier 5: CategoricalNB
Python Classifier 6: ClassifierChain
Python Classifier 7: ComplementNB
Python Classifier 8: DecisionTreeClassifier
Python Classifier 9: DummyClassifier
Python Classifier 10: ExtraTreeClassifier
Python Classifier 11: ExtraTreesClassifier
Python Classifier 12: GaussianNB
Python Classifier 13: GaussianProcessClassifier
Python Classifier 14: GradientBoostingClassifier
Python Classifier 15: HistGradientBoostingClassifier
Python Classifier 16: KNeighborsClassifier
Python Classifier 17: LabelPropagation
Python Classifier 18: LabelSpreading
Python Classifier 19: LinearDiscriminantAnalysis
Python Classifier 20: LinearSVC
Python Classifier 21: LogisticRegression
Python Classifier 22: LogisticRegressionCV
Python Classifier 23: MLPClassifier
Python Classifier 24: MultiOutputClassifier
Python Classifier 25: MultinomialNB
Python Classifier 26: NearestCentroid
Python Classifier 27: NuSVC
Python Classifier 28: OneVsOneClassifier
Python Classifier 29: OneVsRestClassifier
Python Classifier 30: OutputCodeClassifier
Python Classifier 31: PassiveAggressiveClassifier
Python Classifier 32: Perceptron
Python Classifier 33: QuadraticDiscriminantAnalysis
Python Classifier 34: RadiusNeighborsClassifier
Python Classifier 35: RandomForestClassifier
Python Classifier 36: RidgeClassifier
Python Classifier 37: RidgeClassifierCV
Python Classifier 38: SGDClassifier
Python Classifier 39: SVC
Python Classifier 40: StackingClassifier
Python Classifier 41: VotingClassifier
Bu sınıflandırıcılar listesinde kolaylık sağlamak için farklı renklerle vurgulanmışlardır. Temel sınıflandırıcılara ihtiyaç duyan modeller sarı renkle vurgulanmıştır, diğer modeller ise bağımsız olarak kullanılabilir.
İleriye baktığımızda, yeşil renkli modellerin ONNX formatına başarıyla aktarıldığını, kırmızı renkli modellerin ise scikit-learn 1.2.2'nin mevcut sürümünde dönüştürme sırasında hatalarla karşılaştığını belirtmek gerekir.
Modellerde farklı çıktı temsilleri
Farklı modellerin çıktı verilerini farklı şekilde temsil ettiği unutulmamalıdır, bu nedenle ONNX'e dönüştürülen modellerle çalışırken dikkatli olunmalıdır.
Fisher'ın iris sınıflandırma görevi için, girdi tensörleri tüm bu modeller için aynı biçime sahiptir:
1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
ONNX modellerinin çıktı tensörleri farklıdır.
1. İleri işleme gerektirmeyen modeller:
- SVC Classifier;
- LinearSVC Classifier;
- NuSVC Classifier;
- Radius Neighbors Classifier;
- Ridge Classifier;
- Ridge Classifier CV.
1. Name: label, Data Type: tensor(int64), Shape: [None]
2. Name: probabilities, Data Type: tensor(float), Shape: [None, 3]
Bu modeller sonucu (sınıf numarasını) ileri işleme gerektirmeden ilk çıktı tamsayı tensörü "label" içinde açıkça geri döndürür.
2. Sonuçları ileri işleme gerektiren modeller:
- Random Forest Classifier;
- Gradient Boosting Classifier;
- AdaBoost Classifier;
- Bagging Classifier;
- K-NN_Classifier;
- Decision Tree Classifier;
- Logistic Regression Classifier;
- Logistic Regression CV Classifier;
- Passive-Aggressive Classifier;
- Perceptron Classifier;
- SGD Classifier;
- Gaussian Naive Bayes Classifier;
- Multinomial Naive Bayes Classifier;
- Complement Naive Bayes Classifier;
- Bernoulli Naive Bayes Classifier;
- Multilayer Perceptron Classifier;
- Linear Discriminant Analysis Classifier;
- Hist Gradient Boosting Classifier;
- Categorical Naive Bayes Classifier;
- ExtraTree Classifier;
- ExtraTrees Classifier.
1. Name: output_label, Data Type: tensor(int64), Shape: [None]
2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Bu modeller, sınıfların ve her bir sınıfa ait olma olasılıklarının bir listesini geri döndürür.
Bu durumlarda sonucu elde etmek için, seq(map(int64, tensor(float)) (en yüksek olasılığa sahip öğeyi bulma) gibi ileri işleme gereklidir.
Bu nedenle, ONNX modelleriyle çalışırken dikkatli olmak ve bu hususları göz önünde bulundurmak çok önemlidir. Farklı sonuç işlemeye ilişkin bir örnek 2.28.2'deki komut dosyasında sunulmuştur.
iris.mqh
Modelleri MQL5'te tam iris veri kümesi üzerinde test etmek için veri hazırlığı gereklidir. Bu amaçla PrepareIrisDataset() fonksiyonu kullanılacaktır.
Bu fonksiyonları iris.mqh dosyasına taşımak uygundur.
//+------------------------------------------------------------------+ //| Iris.mqh | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| Structure for the IRIS Dataset sample | //+------------------------------------------------------------------+ struct sIRISsample { int sample_id; // sample id (1-150) double features[4]; // SepalLengthCm,SepalWidthCm,PetalLengthCm,PetalWidthCm string class_name; // class ("Iris-setosa","Iris-versicolor","Iris-virginica") int class_id; // class id (0,1,2), calculated by function IRISClassID }; //--- Iris dataset sIRISsample ExtIRISDataset[]; int Exttotal=0; //+------------------------------------------------------------------+ //| Returns class id by class name | //+------------------------------------------------------------------+ int IRISClassID(string class_name) { //--- if(class_name=="Iris-setosa") return(0); else if(class_name=="Iris-versicolor") return(1); else if(class_name=="Iris-virginica") return(2); //--- return(-1); } //+------------------------------------------------------------------+ //| AddSample | //+------------------------------------------------------------------+ bool AddSample(const int Id,const double SepalLengthCm,const double SepalWidthCm,const double PetalLengthCm,const double PetalWidthCm, const string Species) { //--- ExtIRISDataset[Exttotal].sample_id=Id; //--- ExtIRISDataset[Exttotal].features[0]=SepalLengthCm; ExtIRISDataset[Exttotal].features[1]=SepalWidthCm; ExtIRISDataset[Exttotal].features[2]=PetalLengthCm; ExtIRISDataset[Exttotal].features[3]=PetalWidthCm; //--- ExtIRISDataset[Exttotal].class_name=Species; ExtIRISDataset[Exttotal].class_id=IRISClassID(Species); //--- Exttotal++; //--- return(true); } //+------------------------------------------------------------------+ //| Prepare Iris Dataset | //+------------------------------------------------------------------+ bool PrepareIrisDataset(sIRISsample &iris_samples[]) { ArrayResize(ExtIRISDataset,150); Exttotal=0; //--- AddSample(1,5.1,3.5,1.4,0.2,"Iris-setosa"); AddSample(2,4.9,3.0,1.4,0.2,"Iris-setosa"); AddSample(3,4.7,3.2,1.3,0.2,"Iris-setosa"); AddSample(4,4.6,3.1,1.5,0.2,"Iris-setosa"); AddSample(5,5.0,3.6,1.4,0.2,"Iris-setosa"); AddSample(6,5.4,3.9,1.7,0.4,"Iris-setosa"); AddSample(7,4.6,3.4,1.4,0.3,"Iris-setosa"); AddSample(8,5.0,3.4,1.5,0.2,"Iris-setosa"); AddSample(9,4.4,2.9,1.4,0.2,"Iris-setosa"); AddSample(10,4.9,3.1,1.5,0.1,"Iris-setosa"); AddSample(11,5.4,3.7,1.5,0.2,"Iris-setosa"); AddSample(12,4.8,3.4,1.6,0.2,"Iris-setosa"); AddSample(13,4.8,3.0,1.4,0.1,"Iris-setosa"); AddSample(14,4.3,3.0,1.1,0.1,"Iris-setosa"); AddSample(15,5.8,4.0,1.2,0.2,"Iris-setosa"); AddSample(16,5.7,4.4,1.5,0.4,"Iris-setosa"); AddSample(17,5.4,3.9,1.3,0.4,"Iris-setosa"); AddSample(18,5.1,3.5,1.4,0.3,"Iris-setosa"); AddSample(19,5.7,3.8,1.7,0.3,"Iris-setosa"); AddSample(20,5.1,3.8,1.5,0.3,"Iris-setosa"); AddSample(21,5.4,3.4,1.7,0.2,"Iris-setosa"); AddSample(22,5.1,3.7,1.5,0.4,"Iris-setosa"); AddSample(23,4.6,3.6,1.0,0.2,"Iris-setosa"); AddSample(24,5.1,3.3,1.7,0.5,"Iris-setosa"); AddSample(25,4.8,3.4,1.9,0.2,"Iris-setosa"); AddSample(26,5.0,3.0,1.6,0.2,"Iris-setosa"); AddSample(27,5.0,3.4,1.6,0.4,"Iris-setosa"); AddSample(28,5.2,3.5,1.5,0.2,"Iris-setosa"); AddSample(29,5.2,3.4,1.4,0.2,"Iris-setosa"); AddSample(30,4.7,3.2,1.6,0.2,"Iris-setosa"); AddSample(31,4.8,3.1,1.6,0.2,"Iris-setosa"); AddSample(32,5.4,3.4,1.5,0.4,"Iris-setosa"); AddSample(33,5.2,4.1,1.5,0.1,"Iris-setosa"); AddSample(34,5.5,4.2,1.4,0.2,"Iris-setosa"); AddSample(35,4.9,3.1,1.5,0.2,"Iris-setosa"); AddSample(36,5.0,3.2,1.2,0.2,"Iris-setosa"); AddSample(37,5.5,3.5,1.3,0.2,"Iris-setosa"); AddSample(38,4.9,3.6,1.4,0.1,"Iris-setosa"); AddSample(39,4.4,3.0,1.3,0.2,"Iris-setosa"); AddSample(40,5.1,3.4,1.5,0.2,"Iris-setosa"); AddSample(41,5.0,3.5,1.3,0.3,"Iris-setosa"); AddSample(42,4.5,2.3,1.3,0.3,"Iris-setosa"); AddSample(43,4.4,3.2,1.3,0.2,"Iris-setosa"); AddSample(44,5.0,3.5,1.6,0.6,"Iris-setosa"); AddSample(45,5.1,3.8,1.9,0.4,"Iris-setosa"); AddSample(46,4.8,3.0,1.4,0.3,"Iris-setosa"); AddSample(47,5.1,3.8,1.6,0.2,"Iris-setosa"); AddSample(48,4.6,3.2,1.4,0.2,"Iris-setosa"); AddSample(49,5.3,3.7,1.5,0.2,"Iris-setosa"); AddSample(50,5.0,3.3,1.4,0.2,"Iris-setosa"); AddSample(51,7.0,3.2,4.7,1.4,"Iris-versicolor"); AddSample(52,6.4,3.2,4.5,1.5,"Iris-versicolor"); AddSample(53,6.9,3.1,4.9,1.5,"Iris-versicolor"); AddSample(54,5.5,2.3,4.0,1.3,"Iris-versicolor"); AddSample(55,6.5,2.8,4.6,1.5,"Iris-versicolor"); AddSample(56,5.7,2.8,4.5,1.3,"Iris-versicolor"); AddSample(57,6.3,3.3,4.7,1.6,"Iris-versicolor"); AddSample(58,4.9,2.4,3.3,1.0,"Iris-versicolor"); AddSample(59,6.6,2.9,4.6,1.3,"Iris-versicolor"); AddSample(60,5.2,2.7,3.9,1.4,"Iris-versicolor"); AddSample(61,5.0,2.0,3.5,1.0,"Iris-versicolor"); AddSample(62,5.9,3.0,4.2,1.5,"Iris-versicolor"); AddSample(63,6.0,2.2,4.0,1.0,"Iris-versicolor"); AddSample(64,6.1,2.9,4.7,1.4,"Iris-versicolor"); AddSample(65,5.6,2.9,3.6,1.3,"Iris-versicolor"); AddSample(66,6.7,3.1,4.4,1.4,"Iris-versicolor"); AddSample(67,5.6,3.0,4.5,1.5,"Iris-versicolor"); AddSample(68,5.8,2.7,4.1,1.0,"Iris-versicolor"); AddSample(69,6.2,2.2,4.5,1.5,"Iris-versicolor"); AddSample(70,5.6,2.5,3.9,1.1,"Iris-versicolor"); AddSample(71,5.9,3.2,4.8,1.8,"Iris-versicolor"); AddSample(72,6.1,2.8,4.0,1.3,"Iris-versicolor"); AddSample(73,6.3,2.5,4.9,1.5,"Iris-versicolor"); AddSample(74,6.1,2.8,4.7,1.2,"Iris-versicolor"); AddSample(75,6.4,2.9,4.3,1.3,"Iris-versicolor"); AddSample(76,6.6,3.0,4.4,1.4,"Iris-versicolor"); AddSample(77,6.8,2.8,4.8,1.4,"Iris-versicolor"); AddSample(78,6.7,3.0,5.0,1.7,"Iris-versicolor"); AddSample(79,6.0,2.9,4.5,1.5,"Iris-versicolor"); AddSample(80,5.7,2.6,3.5,1.0,"Iris-versicolor"); AddSample(81,5.5,2.4,3.8,1.1,"Iris-versicolor"); AddSample(82,5.5,2.4,3.7,1.0,"Iris-versicolor"); AddSample(83,5.8,2.7,3.9,1.2,"Iris-versicolor"); AddSample(84,6.0,2.7,5.1,1.6,"Iris-versicolor"); AddSample(85,5.4,3.0,4.5,1.5,"Iris-versicolor"); AddSample(86,6.0,3.4,4.5,1.6,"Iris-versicolor"); AddSample(87,6.7,3.1,4.7,1.5,"Iris-versicolor"); AddSample(88,6.3,2.3,4.4,1.3,"Iris-versicolor"); AddSample(89,5.6,3.0,4.1,1.3,"Iris-versicolor"); AddSample(90,5.5,2.5,4.0,1.3,"Iris-versicolor"); AddSample(91,5.5,2.6,4.4,1.2,"Iris-versicolor"); AddSample(92,6.1,3.0,4.6,1.4,"Iris-versicolor"); AddSample(93,5.8,2.6,4.0,1.2,"Iris-versicolor"); AddSample(94,5.0,2.3,3.3,1.0,"Iris-versicolor"); AddSample(95,5.6,2.7,4.2,1.3,"Iris-versicolor"); AddSample(96,5.7,3.0,4.2,1.2,"Iris-versicolor"); AddSample(97,5.7,2.9,4.2,1.3,"Iris-versicolor"); AddSample(98,6.2,2.9,4.3,1.3,"Iris-versicolor"); AddSample(99,5.1,2.5,3.0,1.1,"Iris-versicolor"); AddSample(100,5.7,2.8,4.1,1.3,"Iris-versicolor"); AddSample(101,6.3,3.3,6.0,2.5,"Iris-virginica"); AddSample(102,5.8,2.7,5.1,1.9,"Iris-virginica"); AddSample(103,7.1,3.0,5.9,2.1,"Iris-virginica"); AddSample(104,6.3,2.9,5.6,1.8,"Iris-virginica"); AddSample(105,6.5,3.0,5.8,2.2,"Iris-virginica"); AddSample(106,7.6,3.0,6.6,2.1,"Iris-virginica"); AddSample(107,4.9,2.5,4.5,1.7,"Iris-virginica"); AddSample(108,7.3,2.9,6.3,1.8,"Iris-virginica"); AddSample(109,6.7,2.5,5.8,1.8,"Iris-virginica"); AddSample(110,7.2,3.6,6.1,2.5,"Iris-virginica"); AddSample(111,6.5,3.2,5.1,2.0,"Iris-virginica"); AddSample(112,6.4,2.7,5.3,1.9,"Iris-virginica"); AddSample(113,6.8,3.0,5.5,2.1,"Iris-virginica"); AddSample(114,5.7,2.5,5.0,2.0,"Iris-virginica"); AddSample(115,5.8,2.8,5.1,2.4,"Iris-virginica"); AddSample(116,6.4,3.2,5.3,2.3,"Iris-virginica"); AddSample(117,6.5,3.0,5.5,1.8,"Iris-virginica"); AddSample(118,7.7,3.8,6.7,2.2,"Iris-virginica"); AddSample(119,7.7,2.6,6.9,2.3,"Iris-virginica"); AddSample(120,6.0,2.2,5.0,1.5,"Iris-virginica"); AddSample(121,6.9,3.2,5.7,2.3,"Iris-virginica"); AddSample(122,5.6,2.8,4.9,2.0,"Iris-virginica"); AddSample(123,7.7,2.8,6.7,2.0,"Iris-virginica"); AddSample(124,6.3,2.7,4.9,1.8,"Iris-virginica"); AddSample(125,6.7,3.3,5.7,2.1,"Iris-virginica"); AddSample(126,7.2,3.2,6.0,1.8,"Iris-virginica"); AddSample(127,6.2,2.8,4.8,1.8,"Iris-virginica"); AddSample(128,6.1,3.0,4.9,1.8,"Iris-virginica"); AddSample(129,6.4,2.8,5.6,2.1,"Iris-virginica"); AddSample(130,7.2,3.0,5.8,1.6,"Iris-virginica"); AddSample(131,7.4,2.8,6.1,1.9,"Iris-virginica"); AddSample(132,7.9,3.8,6.4,2.0,"Iris-virginica"); AddSample(133,6.4,2.8,5.6,2.2,"Iris-virginica"); AddSample(134,6.3,2.8,5.1,1.5,"Iris-virginica"); AddSample(135,6.1,2.6,5.6,1.4,"Iris-virginica"); AddSample(136,7.7,3.0,6.1,2.3,"Iris-virginica"); AddSample(137,6.3,3.4,5.6,2.4,"Iris-virginica"); AddSample(138,6.4,3.1,5.5,1.8,"Iris-virginica"); AddSample(139,6.0,3.0,4.8,1.8,"Iris-virginica"); AddSample(140,6.9,3.1,5.4,2.1,"Iris-virginica"); AddSample(141,6.7,3.1,5.6,2.4,"Iris-virginica"); AddSample(142,6.9,3.1,5.1,2.3,"Iris-virginica"); AddSample(143,5.8,2.7,5.1,1.9,"Iris-virginica"); AddSample(144,6.8,3.2,5.9,2.3,"Iris-virginica"); AddSample(145,6.7,3.3,5.7,2.5,"Iris-virginica"); AddSample(146,6.7,3.0,5.2,2.3,"Iris-virginica"); AddSample(147,6.3,2.5,5.0,1.9,"Iris-virginica"); AddSample(148,6.5,3.0,5.2,2.0,"Iris-virginica"); AddSample(149,6.2,3.4,5.4,2.3,"Iris-virginica"); AddSample(150,5.9,3.0,5.1,1.8,"Iris-virginica"); //--- ArrayResize(iris_samples,150); for(int i=0; i<Exttotal; i++) { iris_samples[i]=ExtIRISDataset[i]; } //--- return(true); } //+------------------------------------------------------------------+
Üç popüler sınıflandırma yöntemini karşılaştıralım: SVC (Support Vector Classification), LinearSVC (Linear Support Vector Classification) ve NuSVC (Nu Support Vector Classification).
Çalışma prensipleri:
SVC (Support Vector Classification)
Çalışma prensibi: SVC, sınıflar arasındaki marjın maksimize edilmesine dayanan bir sınıflandırma yöntemidir. Sınıfları maksimum düzeyde ayıran ve hiperdüzleme en yakın noktalar olan destek vektörlerini destekleyen optimum bir ayırıcı hiperdüzlem arar.
Çekirdek fonksiyonları: SVC lineer, radyal temel fonksiyon (RBF), polinom vb. gibi çeşitli çekirdek fonksiyonları kullanabilir. Çekirdek fonksiyonu, optimum hiperdüzlemi bulmak için verilerin nasıl dönüştürüleceğini belirler.
LinearSVC (Linear Support Vector Classification)
Çalışma prensibi: LinearSVC, lineer sınıflandırma konusunda özelleşmiş bir SVC çeşididir. Çekirdek fonksiyonlarını kullanmadan optimum bir doğrusal ayırıcı hiperdüzlem arar. Bu, büyük hacimli verilerle çalışırken daha hızlı ve daha verimli olmasını sağlar.
NuSVC (Nu Support Vector Classification)
Çalışma prensibi: NuSVC de destek vektör yöntemlerine dayanır ancak modelin karmaşıklığını ve destek vektörlerinin oranını kontrol eden bir Nu (nu) parametresi ekler. Nu değeri 0 ila 1 aralığındadır ve verilerin ne kadarının destek vektörleri ve hatalar için kullanılabileceğini belirler.
Avantajlar:
SVC
Güçlü algoritma: SVC, çekirdek fonksiyonlarının kullanımı sayesinde karmaşık sınıflandırma görevlerinin üstesinden gelebilir ve doğrusal olmayan verilerle çalışabilir.
Aykırı değerlere karşı dayanıklılık: SVC, ayırıcı hiperdüzlemi oluşturmak için destek vektörlerini kullandığından veri aykırı değerlerine karşı dayanıklıdır.
LinearSVC
Yüksek verimlilik: LinearSVC, özellikle çok fazla veri olduğunda ve doğrusal ayırma görev için uygun olduğunda, büyük veri kümeleriyle uğraşırken daha hızlı ve daha verimlidir.
Lineer sınıflandırma: Problem doğrusal olarak iyi ayrıştırılabiliyorsa, LinearSVC karmaşık çekirdek fonksiyonlarına ihtiyaç duymadan iyi sonuçlar verebilir.
NuSVC
Model karmaşıklığı kontrolü: NuSVC'deki Nu parametresi, modelin karmaşıklığını ve verilere uyum ile genelleme arasındaki dengeyi kontrol etmenizi sağlar.
Aykırı değerlere karşı dayanıklılık: SVC'ye benzer şekilde, NuSVC de aykırı değerlere karşı dayanıklıdır, bu da onu gürültülü verilere sahip görevler için kullanışlı hale getirir.
Sınırlamalar:
SVC
Hesaplama karmaşıklığı: SVC büyük veri kümelerinde ve/veya karmaşık çekirdek fonksiyonları kullanıldığında yavaş olabilir.
Çekirdek hassasiyeti: Doğru çekirdek fonksiyonunu seçmek zorlu bir görev olabilir ve model performansını önemli ölçüde etkileyebilir.
LinearSVC
Doğrusallık kısıtı: LinearSVC doğrusal veri ayrımı ile kısıtlanır ve özellikler ile hedef değişken arasında doğrusal olmayan bağımlılıkların olduğu durumlarda kötü performans gösterebilir.
NuSVC
Nu parametresinin ayarlanması: Nu parametresinin ayarlanması, optimum sonuçlara ulaşmak için zaman ve deneme gerektirebilir.
Görev karakteristiğine ve veri hacmine bağlı olarak, bu yöntemlerin her biri en iyi seçim olabilir. Denemeler yapmak ve belirli sınıflandırma görevi gereksinimlerine en uygun yöntemi seçmek önemlidir.
2.1. SVC Classifier
Support Vector Classification (SVC) sınıflandırma yöntemi, sınıflandırma görevlerini çözmek için yaygın olarak kullanılan güçlü bir makine öğrenimi algoritmasıdır.
Çalışma prensipleri:
- Optimum ayırıcı hiperdüzlem
Çalışma prensibi: SVC'nin arkasındaki ana fikir, özellik uzayında optimum ayırıcı hiperdüzlemi bulmaktır. Bu hiperdüzlem, farklı sınıflardaki nesneler arasındaki ayrımı en üst düzeye çıkarmalı ve hiperdüzleme en yakın veri noktaları olan destek vektörlerini desteklemelidir.
Marjı en üst düzeye çıkarma: SVC, destek vektörlerinin hiperdüzleme olan uzaklığı anlamına gelen sınıflar arasındaki marjı maksimize etmeyi amaçlar. Bu, yöntemin aykırı değerlere karşı dayanıklı olmasını ve yeni verilere iyi genelleme yapmasını sağlar. - Çekirdek fonksiyonlarının kullanımı
Çekirdek fonksiyonları: SVC lineer, radyal temel fonksiyon (RBF), polinom vb. gibi çeşitli çekirdek fonksiyonları kullanabilir. Çekirdek fonksiyonu, orijinal veri uzayında doğrusal ayrılabilirlik olmasa bile, verilerin görevin doğrusal hale geldiği daha yüksek boyutlu bir uzaya yansıtılmasına olanak tanır.
Çekirdek seçimi: Doğru çekirdek fonksiyonunun seçilmesi SVC modelinin performansını önemli ölçüde etkileyebilir. Doğrusal bir hiperdüzlem her zaman en uygun çözüm değildir.
Avantajlar:
- Güçlü algoritma. Karmaşık görevlerin üstesinden gelme: SVC, özellikler ve hedef değişken arasında doğrusal olmayan bağımlılıklar olanlar da dahil olmak üzere karmaşık sınıflandırma görevlerini çözebilir.
- Aykırı değerlere karşı dayanıklılık: Destek vektörlerinin kullanılması, yöntemi veri aykırı değerlerine karşı dayanıklı hale getirir. Tüm veri kümesi yerine destek vektörlerine bağlıdır.
- Çekirdek esnekliği. Verilere uyarlanabilirlik: Farklı çekirdek fonksiyonları kullanma yeteneği, SVC'nin belirli verilere uyum sağlamasına ve doğrusal olmayan ilişkileri keşfetmesine olanak tanır.
- İyi genelleme. Yeni verilere genelleme: SVC modeli yeni verilere iyi bir şekilde genellenebilir ve bu da onu tahmin görevleri için kullanışlı hale getirir.
Sınırlamalar:
- Hesaplama karmaşıklığı. Eğitim süresi: SVC'nin eğitilmesi, özellikle büyük hacimli verilerle veya karmaşık çekirdek fonksiyonlarıyla uğraşırken yavaş olabilir.
- Çekirdek seçimi. Doğru çekirdek fonksiyonunu seçme: Doğru çekirdek fonksiyonunun seçilmesi denemeler yapmayı gerektirebilir ve veri karakteristiğine bağlıdır.
- Özellik ölçeklendirmesine duyarlılık. Veri normalleştirme: SVC özellik ölçeklendirmesine duyarlıdır, bu nedenle eğitimden önce verilerin normalleştirilmesi veya standartlaştırılması önerilir.
- Model yorumlanabilirliği. Yorumlama karmaşıklığı: Doğrusal olmayan çekirdeklerin ve çok sayıda destek vektörünün kullanılması nedeniyle SVC modellerinin yorumlanması karmaşık olabilir.
Özel göreve ve veri hacmine bağlı olarak, SVC yöntemi sınıflandırma görevlerini çözmek için güçlü bir araç olabilir. Bununla birlikte, optimum sonuçlar elde etmek için sınırlamalarını dikkate almak ve parametreleri ayarlamak çok önemlidir.
2.1.1. SVC Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir SVC Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_SVCClassifier.py # The code demonstrates the process of training SVC model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.svm import SVC from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 an SVC Classifier model with a linear kernel svc_model = SVC(kernel='linear', C=1.0) # train the model on the entire dataset svc_model.fit(X, y) # predict classes for the entire dataset y_pred = svc_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of SVC Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(svc_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path +"svc_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of SVC Classifier model in ONNX format:", accuracy_onnx)
MetaEditor'da "Derle" düğmesini kullanarak kodu çalıştırdıktan sonra, yürütme sonuçlarını Günlük sekmesinde görüntüleyebilirsiniz.
Şekil 12. MetaEditor'da Iris_SVMClassifier.py komut dosyasının sonuçları
Iris_SVCClassifier.py komut dosyasının çıktısı:
Python Accuracy of SVC Classifier model: 0.9933333333333333
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 0.98 0.99 50
Python 2 0.98 1.00 0.99 50
Python
Python accuracy 0.99 150
Python macro avg 0.99 0.99 0.99 150
Python weighted avg 0.99 0.99 0.99 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\svc_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: probabilities, Data Type: tensor(float), Shape: [None, 3]
Python
Python Accuracy of SVC Classifier model in ONNX format: 0.9933333333333333
Burada, ONNX modelinin kaydedildiği yol, ONNX modelinin girdi ve çıktı parametrelerinin türleri ve iris veri setini tanımlamadaki doğruluk hakkında bilgi bulabilirsiniz.
SVM Classifier’ı kullanarak veri kümesini tanımlama doğruluğu %99'dur ve ONNX formatına aktarılan model de aynı doğruluk seviyesini göstermektedir.
Şimdi, 150 veri örneğinin her biri için oluşturulan modeli çalıştırarak bu sonuçları MQL5'te doğrulayacağız. Ek olarak, komut dosyası bir toplu veri işleme örneği de içermektedir.
2.1.2. SVC Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_SVCClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "svc_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- ulong input_shape[]= { batch_size, input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- int output1[]; float output2[][3]; //--- ArrayResize(output1,(int)batch_size); ArrayResize(output2,(int)batch_size); //--- ulong output_shape[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape); //--- ulong output_shape2[]= {batch_size,3}; OnnxSetOutputShape(model,1,output_shape2); //--- bool res=OnnxRun(model,ONNX_DEBUG_LOGS,input_data,output1,output2); //--- classes are ready in output1[k]; if(res) { for(int k=0; k<(int)batch_size; k++) model_classes_id[k]=output1[k]; } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="SVCClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Komut dosyasının yürütülmesinin sonuçları MetaTrader 5 terminalinin "Uzmanlar" sekmesinde görüntülenir.
Iris_SVCClassifier (EURUSD,H1) model:SVCClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_SVCClassifier (EURUSD,H1) model:SVCClassifier correct results: 99.33% Iris_SVCClassifier (EURUSD,H1) model=SVCClassifier all samples accuracy=0.993333 Iris_SVCClassifier (EURUSD,H1) model=SVCClassifier batch test accuracy=1.000000
SVC modeli 150 örnekten 149'unu doğru bir şekilde sınıflandırmıştır ki bu mükemmel bir sonuçtur. Model, iris veri setinde sadece bir sınıflandırma hatası yapmış ve 84 numaralı örnek için sınıf 1 (virginica) yerine sınıf 2 (versicolor) tahmininde bulunmuştur.
Dışa aktarılan ONNX modelinin tam iris veri setindeki doğruluğunun %99.33 olduğunu ve bunun orijinal modelin doğruluğuyla eşleştiğini belirtmek gerekir.
2.1.3. SVC Classifier modelinin ONNX gösterimi
Oluşturulan ONNX modelini MetaEditor'da görüntüleyebilirsiniz.
Şekil 13. MetaEditor'da svc_iris.onnx ONNX modeli
Modelin mimarisi hakkında daha ayrıntılı bilgi için Netron'u kullanabilirsiniz. Bunu yapmak için, MetaEditor'da modelin açıklamasındaki "Netron'da aç" düğmesine tıklayın.
Şekil 14. Şekil 14. Netron'da svc_iris.onnx ONNX modeli
Şekil 15. Netron'da svc_iris.onnx ONNX modeli (SVMClassifier ONNX operatör parametreleri)
2.2. LinearSVC Classifier
LinearSVC (Linear Support Vector Classification), ikili ve çok sınıflı sınıflandırma görevleri için kullanılan güçlü bir makine öğrenimi algoritmasıdır. Verileri en iyi şekilde ayıran bir hiperdüzlem bulma fikrine dayanır.
LinearSVC’nin prensipleri:
- Optimum hiperdüzlemin bulunması: LinearSVC'nin ana fikri, iki veri sınıfını maksimum düzeyde ayıran en uygun hiperdüzlemi bulmaktır. Bir hiperdüzlem, doğrusal bir denklemle tanımlanan çok boyutlu bir düzlemdir.
- Marjın en aza indirilmesi: LinearSVC, marjları (veri noktaları ile hiperdüzlem arasındaki mesafeler) en aza indirmeyi amaçlar. Marjlar ne kadar büyük olursa, hiperdüzlem sınıfları o kadar etkili bir şekilde ayırır.
- Doğrusal olarak ayrıştırılamayan verilerin işlenmesi: LinearSVC, verileri doğrusal olarak ayrılabilecekleri daha yüksek boyutlu bir uzaya yansıtan çekirdek fonksiyonlarının (kernel trick) kullanımı sayesinde orijinal özellik uzayında doğrusal olarak ayrılamayan verilerle çalışabilir.
LinearSVC'nin avantajları:
- İyi genelleme: LinearSVC iyi bir genelleme yeteneğine sahiptir ve yeni, görülmemiş veriler üzerinde iyi performans gösterebilir.
- Verimlilik: LinearSVC büyük veri kümeleri üzerinde hızlı bir şekilde çalışır ve nispeten az hesaplama kaynağı gerektirir.
- Doğrusal olarak ayrıştırılamayan verilerin işlenmesi: LinearSVC, çekirdek fonksiyonlarını kullanarak doğrusal olarak ayrılamayan verilerle sınıflandırma görevlerini yerine getirebilir.
- Ölçeklenebilirlik: LinearSVC, çok sayıda özelliğe ve önemli veri hacimlerine sahip görevlerde verimli bir şekilde kullanılabilir.
LinearSVC'nin sınırlamaları:
- Sadece doğrusal ayırıcı hiperdüzlemler: LinearSVC yalnızca doğrusal ayırıcı hiperdüzlemler oluşturur, bu da doğrusal olmayan bağımlılıklara sahip karmaşık sınıflandırma görevleri için yetersiz olabilir.
- Parametre seçimi: Doğru parametrelerin seçilmesi (örneğin, düzenlileştirme parametresi) uzman bilgisi veya çapraz doğrulama gerektirebilir.
- Aykırı değerlere hassasiyet: LinearSVC, verilerdeki aykırı değerlere karşı hassas olabilir ve bu da sınıflandırma kalitesini etkileyebilir.
- Model yorumlanabilirliği: LinearSVC kullanılarak oluşturulan modeller, diğer bazı yöntemlere kıyasla daha az yorumlanabilir olabilir.
LinearSVC, genelleme, verimlilik ve doğrusal olarak ayrılamayan verileri işleme konusunda üstün olan güçlü bir sınıflandırma algoritmasıdır. Özellikle veriler doğrusal bir hiperdüzlemle ayrılabildiğinde, çeşitli sınıflandırma görevlerinde uygulama alanı bulur. Bununla birlikte, doğrusal olmayan bağımlılıkların modellenmesini gerektiren karmaşık görevler için LinearSVC daha az uygun olabilir ve bu gibi durumlarda, daha karmaşık karar sınırlarına sahip alternatif yöntemler düşünülmelidir.
2.2.1. LinearSVC Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir LinearSVC Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_LinearSVC.py # The code demonstrates the process of training LinearSVC model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.svm import LinearSVC from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a LinearSVC model linear_svc_model = LinearSVC(C=1.0, max_iter=10000) # train the model on the entire dataset linear_svc_model.fit(X, y) # predict classes for the entire dataset y_pred = linear_svc_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of LinearSVC model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(linear_svc_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "linear_svc_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of LinearSVC model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.96 0.94 0.95 50
Python 2 0.94 0.96 0.95 50
Python
Python accuracy 0.97 150
Python macro avg 0.97 0.97 0.97 150
Python weighted avg 0.97 0.97 0.97 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\linear_svc_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: probabilities, Data Type: tensor(float), Shape: [None, 3]
Python
Python Accuracy of LinearSVC model in ONNX format: 0.9666666666666667
2.2.2. LinearSVC Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_LinearSVC.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "linear_svc_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- ulong input_shape[]= { batch_size, input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- int output1[]; float output2[][3]; //--- ArrayResize(output1,(int)batch_size); ArrayResize(output2,(int)batch_size); //--- ulong output_shape[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape); //--- ulong output_shape2[]= {batch_size,3}; OnnxSetOutputShape(model,1,output_shape2); //--- bool res=OnnxRun(model,ONNX_DEBUG_LOGS,input_data,output1,output2); //--- classes are ready in output1[k]; if(res) { for(int k=0; k<(int)batch_size; k++) model_classes_id[k]=output1[k]; } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="LinearSVC"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_LinearSVC (EURUSD,H1) model:LinearSVC sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_LinearSVC (EURUSD,H1) model:LinearSVC sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_LinearSVC (EURUSD,H1) model:LinearSVC sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_LinearSVC (EURUSD,H1) model:LinearSVC sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_LinearSVC (EURUSD,H1) model:LinearSVC sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_LinearSVC (EURUSD,H1) model:LinearSVC correct results: 96.67% Iris_LinearSVC (EURUSD,H1) model=LinearSVC all samples accuracy=0.966667 Iris_LinearSVC (EURUSD,H1) model=LinearSVC batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %96.67'dir ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.2.3. LinearSVC Classifier modelinin ONNX gösterimi
Şekil 16. Netron'da LinearSVC Classifier modelinin ONNX gösterimi
2.3. NuSVC Classifier
Nu-Support Vector Classification (NuSVC) yöntemi, Support Vector Machine (SVM) yaklaşımına dayanan güçlü bir makine öğrenimi algoritmasıdır.
NuSVC’nin prensipleri:
- Support Vector Machine (SVM): NuSVC, ikili ve çok sınıflı sınıflandırma görevleri için kullanılan bir SVM çeşididir. SVM'nin temel prensibi, maksimum marjı korurken sınıfları maksimum düzeyde ayıran optimum ayırıcı hiperdüzlemi bulmaktır.
- Nu parametresi: NuSVC'deki önemli bir parametre, modelin karmaşıklığını kontrol eden ve destek vektörleri ve hatalar olarak kullanılabilecek örneklem oranını tanımlayan Nu parametresidir (nu). Nu değeri 0 ila 1 arasında değişir; burada 0.5, örneğin yaklaşık yarısının destek vektörleri ve hatalar olarak kullanılacağı anlamına gelir.
- Parametre ayarlama: Nu parametresi ve diğer hiperparametreler için en uygun değerlerin belirlenmesi, çapraz doğrulama ve eğitim verileri üzerinde en iyi değerlerin aranmasını gerektirebilir.
- Çekirdek fonksiyonları: NuSVC lineer, radyal temel fonksiyon (RBF), polinom vb. gibi çeşitli çekirdek fonksiyonları kullanabilir. Çekirdek fonksiyonu, ayırıcı hiperdüzlemi bulmak için özellik uzayının nasıl dönüştürüleceğini belirler.
NuSVC'nin avantajları:
- Yüksek boyutlu uzaylarda verimlilik: NuSVC yüksek boyutlu uzaylarda verimli bir şekilde çalışabilir, bu da onu çok sayıda özelliğe sahip görevler için uygun hale getirir.
- Aykırı değerlere karşı dayanıklılık: SVM ve özellikle NuSVC, destek vektörlerinin kullanımı nedeniyle verilerdeki aykırı değerlere karşı dayanıklıdır.
- Model karmaşıklığının kontrolü: Nu parametresi, model karmaşıklığının kontrol edilmesine ve genelleme ile veri uyumunun dengelenmesine olanak tanır.
- İyi genelleme: Özellikle SVM ve NuSVC iyi bir genelleme sergileyerek daha önce görülmemiş yeni veriler üzerinde mükemmel performans sağlar.
NuSVC'nin sınırlamaları:
- Büyük veri hacimlerinde verimsizlik: NuSVC, hesaplama karmaşıklığı nedeniyle büyük veri hacimleri üzerinde eğitildiğinde verimsiz olabilir.
- Parametre ayarlama gereksinimi: Nu parametresinin ve çekirdek fonksiyonunun ayarlanması zaman ve hesaplama kaynakları gerektirebilir.
- Çekirdek fonksiyonu doğrusallığı: NuSVC'nin etkinliği önemli ölçüde çekirdek fonksiyonunun seçimine bağlı olabilir ve bazı görevler için farklı fonksiyonlarla denemeler yapmak gerekebilir.
- Model yorumlanabilirliği: SVM ve NuSVC mükemmel sonuçlar sağlar, ancak özellikle doğrusal olmayan çekirdekler kullanıldığında modellerinin yorumlanması karmaşık olabilir.
Nu-Support Vector Classification (NuSVC), aykırı değerlere karşı sağlamlık ve iyi genelleme gibi çeşitli avantajlara sahip SVM'ye dayalı güçlü bir sınıflandırma yöntemidir. Bununla birlikte, etkinliği parametre ve çekirdek fonksiyonu seçimine bağlıdır ve büyük veri hacimleri için verimsiz olabilir. Parametreleri dikkatlice seçmek ve yöntemi belirli sınıflandırma görevlerine uyarlamak çok önemlidir.
2.3.1. NuSVC Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir NuSVC Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_NuSVC.py # The code demonstrates the process of training NuSVC model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.svm import NuSVC from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a NuSVC model nusvc_model = NuSVC(nu=0.5, kernel='linear') # train the model on the entire dataset nusvc_model.fit(X, y) # predict classes for the entire dataset y_pred = nusvc_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of NuSVC model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(nusvc_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "nusvc_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of NuSVC model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.96 0.96 0.96 50
Python 2 0.96 0.96 0.96 50
Python
Python accuracy 0.97 150
Python macro avg 0.97 0.97 0.97 150
Python weighted avg 0.97 0.97 0.97 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\nusvc_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: probabilities, Data Type: tensor(float), Shape: [None, 3]
Python
Python Accuracy of NuSVC model in ONNX format: 0.9733333333333334
2.3.2. NuSVC Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_NuSVC.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "nusvc_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- ulong input_shape[]= { batch_size, input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- int output1[]; float output2[][3]; //--- ArrayResize(output1,(int)batch_size); ArrayResize(output2,(int)batch_size); //--- ulong output_shape[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape); //--- ulong output_shape2[]= {batch_size,3}; OnnxSetOutputShape(model,1,output_shape2); //--- bool res=OnnxRun(model,ONNX_DEBUG_LOGS,input_data,output1,output2); //--- classes are ready in output1[k]; if(res) { for(int k=0; k<(int)batch_size; k++) model_classes_id[k]=output1[k]; } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="NuSVC"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_NuSVC (EURUSD,H1) model:NuSVC sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_NuSVC (EURUSD,H1) model:NuSVC sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_NuSVC (EURUSD,H1) model:NuSVC sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_NuSVC (EURUSD,H1) model:NuSVC sample=139 FAILED [class=1, true class=2] features=(6.00,3.00,4.80,1.80] Iris_NuSVC (EURUSD,H1) model:NuSVC correct results: 97.33% Iris_NuSVC (EURUSD,H1) model=NuSVC all samples accuracy=0.973333 Iris_NuSVC (EURUSD,H1) model=NuSVC batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %97.33'tür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.3.3. NuSVC Classifier modelinin ONNX gösterimi
Şekil 17. Netron'da NuSVC Classifier modelinin ONNX gösterimi
2.4. Radius Neighbors Classifier
Radius Neighbors Classifier, nesneler arasındaki yakınlık ilkesine dayalı sınıflandırma görevleri için kullanılan bir makine öğrenimi yöntemidir. Sabit sayıda en yakın komşunun (K) seçildiği klasik K-Nearest Neighbors (K-NN) Classifier’ın aksine, Radius Neighbors Classifier’da nesneler belirli bir yarıçap içindeki en yakın komşulara olan uzaklıklarına göre sınıflandırılır.Radius Neighbors Classifier’ın prensipleri:
- Yarıçapın belirlenmesi: Radius Neighbors Classifier’ın ana parametresi, bir nesne ile komşuları arasında nesnenin komşu sınıfa yakın olarak kabul edildiği maksimum mesafeyi tanımlayan yarıçaptır.
- En yakın komşuları bulma: Eğitim veri kümesindeki diğer tüm nesnelere olan uzaklık her nesne için hesaplanır. Belirtilen yarıçap içinde bulunan nesneler, nesnenin komşuları olarak kabul edilir.
- Oylama: Radius Neighbors Classifier, nesnenin sınıfını belirlemek için komşular arasında çoğunluk oylamasını kullanır. Örneğin, komşuların çoğunluğu A sınıfına aitse, nesne de A sınıfı olarak sınıflandırılacaktır.
- Veri yoğunluğuna uyarlanabilirlik: The Radius Neighbors Classifier, farklı özellik uzayı bölgelerindeki veri yoğunluğunun değişebildiği görevler için uygundur.
- Farklı sınıf şekilleri ile çalışabilme becerisi: Bu yöntem, sınıfların karmaşık ve doğrusal olmayan şekillere sahip olduğu görevlerde iyi performans gösterir.
- Aykırı değerler içeren veriler için uygundur: Radius Neighbors Classifier, belirtilen yarıçapın ötesinde bulunan komşuları göz ardı ettiği için aykırı değerlere karşı K-NN'den daha dayanıklıdır.
- Yarıçap seçimine duyarlılık: Optimum yarıçap değerinin seçilmesi basit olmayan bir görev olabilir ve ayarlama gerektirir.
- Büyük veri kümelerinde verimsizlik: Büyük veri kümeleri için, tüm nesnelere olan uzaklıkları hesaplamak hesaplama açısından maliyetli olabilir.
- Veri yoğunluğuna bağımlılık: Veriler özellik uzayında tekdüze olmayan bir yoğunluğa sahip olduğunda bu yöntem daha az verimli olabilir.
Radius Neighbors Classifier, nesne yakınlığının önemli olduğu ve sınıf şekillerinin karmaşık olabileceği durumlarda değerli bir makine öğrenimi yöntemidir. Görüntü analizi, doğal dil işleme vb. çeşitli alanlarda uygulanabilir.
2.4.1. Radius Neighbors Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Radius Neighbors Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_RadiusNeighborsClassifier.py # The code demonstrates the process of training an Radius Neughbors model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023 MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.neighbors import RadiusNeighborsClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Radius Neighbors Classifier model radius_model = RadiusNeighborsClassifier(radius=1.0) # train the model on the entire dataset radius_model.fit(X, y) # predict classes for the entire dataset y_pred = radius_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Radius Neighbors Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(radius_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "radius_neighbors_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Radius Neighbors Classifier model in ONNX format:", accuracy_onnx)
Iris_RadiusNeighbors.py komut dosyasının sonuçları:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.94 0.98 0.96 50
Python 2 0.98 0.94 0.96 50
Python
Python accuracy 0.97 150
Python macro avg 0.97 0.97 0.97 150
Python weighted avg 0.97 0.97 0.97 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\radius_neighbors_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: probabilities, Data Type: tensor(float), Shape: [None, 3]
Python
Python Accuracy of Radius Neighbors Classifier model in ONNX format: 0.9733333333333334
Orijinal modelin doğruluğu ile ONNX formatında dışa aktarılan modelin doğruluğu aynıdır.
2.4.2. Radius Neighbors Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_RadiusNeighborsClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "radius_neighbors_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- ulong input_shape[]= { batch_size, input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- int output1[]; float output2[][3]; //--- ArrayResize(output1,(int)batch_size); ArrayResize(output2,(int)batch_size); //--- ulong output_shape[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape); //--- ulong output_shape2[]= {batch_size,3}; OnnxSetOutputShape(model,1,output_shape2); //--- bool res=OnnxRun(model,ONNX_DEBUG_LOGS,input_data,output1,output2); //--- classes are ready in output1[k]; if(res) { for(int k=0; k<(int)batch_size; k++) model_classes_id[k]=output1[k]; } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="RadiusNeighborsClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_RadiusNeighborsClassifier (EURUSD,H1) model:RadiusNeighborsClassifier sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_RadiusNeighborsClassifier (EURUSD,H1) model:RadiusNeighborsClassifier sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_RadiusNeighborsClassifier (EURUSD,H1) model:RadiusNeighborsClassifier sample=127 FAILED [class=1, true class=2] features=(6.20,2.80,4.80,1.80] Iris_RadiusNeighborsClassifier (EURUSD,H1) model:RadiusNeighborsClassifier sample=139 FAILED [class=1, true class=2] features=(6.00,3.00,4.80,1.80] Iris_RadiusNeighborsClassifier (EURUSD,H1) model:RadiusNeighborsClassifier correct results: 97.33% Iris_RadiusNeighborsClassifier (EURUSD,H1) model=RadiusNeighborsClassifier all samples accuracy=0.973333 Iris_RadiusNeighborsClassifier (EURUSD,H1) model=RadiusNeighborsClassifier batch test accuracy=1.000000
Radius Neighbors Classifier modeli 4 sınıflandırma hatasıyla (78, 107, 127 ve 139 numaralı örnekler) %97.33'lük bir doğruluk oranı göstermiştir.
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %97.33'tür ve bu da orijinal modelin doğruluğuyla eşleşmektedir.
2.4.3. Radius Neighbors Classifier modelinin ONNX gösterimi
Şekil 18. Netron'da Radius Neighbors Classifier modelinin ONNX gösterimi
RidgeClassifier ve RidgeClassifierCV yöntemleri hakkında not
RidgeClassifier ve RidgeClassifierCV, Ridge regresyonuna dayanan iki sınıflandırma yöntemidir, ancak parametrelerin ayarlanma şekli ve hiperparametrelerin otomatik olarak seçilmesi bakımından farklılık gösterirler:
RidgeClassifier:
- RidgeClassifier, ikili ve çok sınıflı sınıflandırma görevleri için kullanılan Ridge regresyonuna dayalı bir sınıflandırma yöntemidir.
- Çok sınıflı sınıflandırma durumunda, RidgeClassifier görevi birden fazla ikili göreve (bire karşı hepsi) dönüştürür ve her biri için bir model oluşturur.
- Alfa düzenlileştirme parametresinin kullanıcı tarafından manuel olarak ayarlanması gerekir, yani denemeler veya doğrulama verilerinin analizi yoluyla en uygun alfa değerini seçmeniz gerekir.
RidgeClassifierCV:
- RidgeClassifierCV, çapraz doğrulama için yerleşik destek ve optimum alfa düzenlileştirme parametresinin otomatik seçimini sağlayan RidgeClassifier'ın bir uzantısıdır.
- Alfa değerini manuel olarak ayarlamak yerine, RidgeClassifierCV'ye araştırılacak alfa değerlerinin bir listesini sağlayabilir ve çapraz doğrulama yöntemini belirtebilirsiniz (örneğin, cv parametresi aracılığıyla).
- RidgeClassifierCV, çapraz doğrulama sırasında en iyi performansı gösteren optimum alfa değerini otomatik olarak seçer.
Dolayısıyla, aralarındaki temel fark, alfa düzenlileştirme parametresi için en uygun değerin seçilmesindeki otomasyon seviyesinde yatmaktadır. RidgeClassifier, alfanın manuel olarak ayarlanmasını gerektirirken RidgeClassifierCV, çapraz doğrulama kullanarak optimum alfa değerinin otomatik olarak seçilmesine olanak tanır. Bunlar arasındaki tercih, ihtiyaçlarınıza ve model ayarlama sürecindeki otomasyon isteğinize bağlıdır.
2.5. Ridge Classifier
Ridge Classifier, modelde L2 düzenlileştirme (Ridge regresyonu) içeren bir lojistik regresyon çeşididir. L2 düzenlileştirme, modelin büyük katsayılarına bir ceza ekleyerek aşırı uyumu azaltmaya ve modelin genelleme yeteneğini geliştirmeye yardımcı olur.
Ridge Classifier’ın prensipleri:
- Olasılıkların tahmini: Lojistik regresyon gibi, Ridge Classifier da lojistik (sigmoid) bir fonksiyon kullanarak bir nesnenin belirli bir sınıfa ait olma olasılığını modeller.
- L2 düzenlileştirme: Ridge Classifier, modelin büyük katsayılarını cezalandıran bir L2 düzenlileştirme terimi ekler. Bu, modelin karmaşıklığını kontrol etmek ve aşırı uyumu azaltmak için yapılır.
- Parametre eğitimi: Ridge Classifier modeli, özellikler ve düzenlileştirme parametresi için ağırlıkları (katsayıları) ayarlamak üzere eğitim veri kümesi üzerinde eğitilir.
Ridge Classifier’ın avantajları:
- Aşırı uyum azaltma: L2 düzenlileştirme, modelin aşırı uyum sağlama eğilimini azaltmaya yardımcı olur, bu da özellikle sınırlı veri olduğunda yararlıdır.
- Çoklu eşdoğrusallığın yönetimi: Ridge Classifier, özelliklerin birbiriyle yüksek oranda ilişkili olduğu çoklu eşdoğrusallık sorunlarını iyi bir şekilde yönetir.
Ridge Classifier’ın sınırlamaları:
- Düzenlileştirme parametresi seçimine duyarlılık: Diğer düzenlileştirme yöntemleri gibi, düzenlileştirme parametresi (alfa) için doğru değeri seçmek ayarlama ve değerlendirme gerektirir.
- Çok sınıflı sınıflandırma kısıtı: Ridge Classifier başlangıçta ikili sınıflandırma için tasarlanmıştır, ancak One-vs-All gibi yaklaşımlar kullanılarak çok sınıflı sınıflandırmaya uyarlanabilir.
Ridge Classifier, aşırı uyumla mücadele etmek ve modelin genelleme yeteneğini geliştirmek için lojistik regresyonun faydalarını düzenlileştirmeyle birleştiren güçlü bir makine öğrenimi yöntemidir. Olasılıksal sınıflandırma ve model karmaşıklığı kontrolünün önemli olduğu çeşitli alanlarda uygulama alanı bulmaktadır.
2.5.1. Ridge Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Ridge Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_RidgeClassifier.py # The code demonstrates the process of training Ridge Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.linear_model import RidgeClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Ridge Classifier model ridge_model = RidgeClassifier() # train the model on the entire dataset ridge_model.fit(X, y) # predict classes for the entire dataset y_pred = ridge_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Ridge Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(ridge_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "ridge_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Ridge Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.87 0.66 0.75 50
Python 2 0.73 0.90 0.80 50
Python
Python accuracy 0.85 150
Python macro avg 0.86 0.85 0.85 150
Python weighted avg 0.86 0.85 0.85 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\ridge_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: probabilities, Data Type: tensor(float), Shape: [None, 3]
Python
Python Accuracy of Ridge Classifier model in ONNX format: 0.8533333333333334
2.5.2. Ridge Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_RidgeClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "ridge_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- ulong input_shape[]= { batch_size, input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- int output1[]; float output2[][3]; //--- ArrayResize(output1,(int)batch_size); ArrayResize(output2,(int)batch_size); //--- ulong output_shape[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape); //--- ulong output_shape2[]= {batch_size,3}; OnnxSetOutputShape(model,1,output_shape2); //--- bool res=OnnxRun(model,ONNX_DEBUG_LOGS,input_data,output1,output2); //--- classes are ready in output1[k]; if(res) { for(int k=0; k<(int)batch_size; k++) model_classes_id[k]=output1[k]; } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="RidgeClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=51 FAILED [class=2, true class=1] features=(7.00,3.20,4.70,1.40] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=52 FAILED [class=2, true class=1] features=(6.40,3.20,4.50,1.50] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=53 FAILED [class=2, true class=1] features=(6.90,3.10,4.90,1.50] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=57 FAILED [class=2, true class=1] features=(6.30,3.30,4.70,1.60] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=62 FAILED [class=2, true class=1] features=(5.90,3.00,4.20,1.50] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=65 FAILED [class=2, true class=1] features=(5.60,2.90,3.60,1.30] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=66 FAILED [class=2, true class=1] features=(6.70,3.10,4.40,1.40] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=67 FAILED [class=2, true class=1] features=(5.60,3.00,4.50,1.50] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=76 FAILED [class=2, true class=1] features=(6.60,3.00,4.40,1.40] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=79 FAILED [class=2, true class=1] features=(6.00,2.90,4.50,1.50] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=86 FAILED [class=2, true class=1] features=(6.00,3.40,4.50,1.60] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=87 FAILED [class=2, true class=1] features=(6.70,3.10,4.70,1.50] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=89 FAILED [class=2, true class=1] features=(5.60,3.00,4.10,1.30] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=92 FAILED [class=2, true class=1] features=(6.10,3.00,4.60,1.40] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=109 FAILED [class=1, true class=2] features=(6.70,2.50,5.80,1.80] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier correct results: 85.33% Iris_RidgeClassifier (EURUSD,H1) model=RidgeClassifier all samples accuracy=0.853333 Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier FAILED [class=2, true class=1] features=(7.00,3.20,4.70,1.40) Iris_RidgeClassifier (EURUSD,H1) model:RidgeClassifier FAILED [class=2, true class=1] features=(6.40,3.20,4.50,1.50) Iris_RidgeClassifier (EURUSD,H1) model=RidgeClassifier batch test accuracy=0.000000
Tam iris veri kümesinde model, orijinalin doğruluğuna karşılık gelen %85.33'lük bir doğruluk göstermiştir.
2.5.3. Ridge Classifier modelinin ONNX gösterimi
Şekil 19. Netron'da Ridge Classifier modelinin ONNX gösterimi
2.6. RidgeClassifierCV
RidgeClassifierCV sınıflandırma yöntemi, Ridge regresyonuna dayalı ikili ve çok sınıflı sınıflandırma için güçlü bir algoritmadır.
RidgeClassifierCV'nin prensipleri:
- Lineer Ridge regresyonu: RidgeClassifierCV lineer Ridge regresyonuna dayanmaktadır. Bu yöntem, L2 düzenlileştirmenin eklendiği lineer regresyonun bir modifikasyonudur. Düzenlileştirme, özellik ağırlıklarının büyüklüğünü azaltarak aşırı uyumu kontrol etmeye yardımcı olur.
- İkili ve çok sınıflı sınıflandırma: RidgeClassifierCV hem ikili sınıflandırma (sadece iki sınıf olduğunda) hem de çok sınıflı sınıflandırma (ikiden fazla sınıf olduğunda) için kullanılabilir. Çok sınıflı sınıflandırma için, görevi birden fazla ikili göreve dönüştürür (bire karşı hepsi) ve her biri için bir model oluşturur.
- Düzenlileştirme parametresinin otomatik seçimi: RidgeClassifierCV'nin en önemli avantajlarından biri, çapraz doğrulama için yerleşik desteği ve optimum alfa düzenlileştirme parametresinin otomatik seçimidir. Alfa değerini manuel olarak ayarlamak yerine, yöntem farklı alfa değerleri üzerinde yineleme yapar ve çapraz doğrulamaya dayalı olarak en iyisini seçer.
- Çoklu eşdoğrusallığın yönetimi: RidgeClassifierCV, özelliklerin birbiriyle yüksek oranda ilişkili olduğu çoklu eşdoğrusallık sorunlarını iyi bir şekilde yönetir. Düzenlileştirme, her bir özelliğin katkısının kontrol edilmesini sağlayarak modeli korelasyonlu verilere karşı dayanıklı hale getirir.
RidgeClassifierCV'nin avantajları:
- Otomatik hiperparametre seçimi: RidgeClassifierCV'nin önemli avantajlarından biri, çapraz doğrulama kullanarak en uygun alfa değerini otomatik olarak seçebilmesidir. Bu, farklı alfa değerleriyle denemeler yapma ihtiyacını ortadan kaldırır ve iyi sonuçlar elde etme olasılığını artırır.
- Aşırı uyum kontrolü: RidgeClassifierCV tarafından sağlanan L2 düzenlileştirme, model karmaşıklığını kontrol etmeye yardımcı olur ve aşırı uyum riskini azaltır. Bu özellikle sınırlı veriye sahip görevler için önemlidir.
- Şeffaflık ve yorumlanabilirlik: RidgeClassifierCV, yorumlanabilir özellik ağırlıkları sağlayarak her bir özelliğin tahminlere katkısının analiz edilmesine ve özelliklerin önemine ilişkin sonuçlar çıkarılmasına olanak tanır.
- Verimlilik: Yöntem oldukça verimlidir ve büyük veri kümelerine uygulanabilir.
RidgeClassifierCV'nin sınırlamaları:
- Doğrusallık: RidgeClassifierCV, özellikler ve hedef değişken arasında doğrusal ilişkiler olduğunu varsayar. Veriler güçlü doğrusal olmayan ilişkiler sergiliyorsa, yöntem yeterince doğru olmayabilir.
- Özellik ölçeklendirme hassasiyeti: Yöntem, özellik ölçeklendirmesine duyarlıdır. RidgeClassifierCV'yi uygulamadan önce özelliklerin standartlaştırılması veya normalleştirilmesi önerilir.
- Optimum özellik seçimi: RidgeClassifierCV otomatik özellik seçimi yapmaz, bu nedenle hangi özelliklerin modele dahil edileceğine manuel olarak karar vermeniz gerekir.
RidgeClassifierCV sınıflandırma yöntemi, optimum düzenlileştirme parametresinin otomatik seçimi ile ikili ve çok sınıflı sınıflandırma için güçlü bir araçtır. Aşırı uyum kontrolü, yorumlanabilirliği ve verimliliği, onu çeşitli sınıflandırma görevleri için popüler bir seçim haline getirmektedir. Bununla birlikte, sınırlamalarını, özellikle de özellikler ve hedef değişken arasındaki doğrusal ilişkiler varsayımını akılda tutmak önemlidir.
2.6.1. RidgeClassifierCV modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir RidgeClassifierCV modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_RidgeClassifierCV.py # The code demonstrates the process of training RidgeClassifierCV model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.linear_model import RidgeClassifierCV from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a RidgeClassifierCV model ridge_classifier_cv_model = RidgeClassifierCV() # train the model on the entire dataset ridge_classifier_cv_model.fit(X, y) # predict classes for the entire dataset y_pred = ridge_classifier_cv_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of RidgeClassifierCV model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(ridge_classifier_cv_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "ridge_classifier_cv_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of RidgeClassifierCV model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.87 0.66 0.75 50
Python 2 0.73 0.90 0.80 50
Python
Python accuracy 0.85 150
Python macro avg 0.86 0.85 0.85 150
Python weighted avg 0.86 0.85 0.85 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\ridge_classifier_cv_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: probabilities, Data Type: tensor(float), Shape: [None, 3]
Python
Python Accuracy of RidgeClassifierCV model in ONNX format: 0.8533333333333334
2.6.2. RidgeClassifierCV modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_RidgeClassifierCV.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "ridge_classifier_cv_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- ulong input_shape[]= { batch_size, input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- int output1[]; float output2[][3]; //--- ArrayResize(output1,(int)batch_size); ArrayResize(output2,(int)batch_size); //--- ulong output_shape[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape); //--- ulong output_shape2[]= {batch_size,3}; OnnxSetOutputShape(model,1,output_shape2); //--- bool res=OnnxRun(model,ONNX_DEBUG_LOGS,input_data,output1,output2); //--- classes are ready in output1[k]; if(res) { for(int k=0; k<(int)batch_size; k++) model_classes_id[k]=output1[k]; } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="RidgeClassifierCV"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=51 FAILED [class=2, true class=1] features=(7.00,3.20,4.70,1.40] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=52 FAILED [class=2, true class=1] features=(6.40,3.20,4.50,1.50] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=53 FAILED [class=2, true class=1] features=(6.90,3.10,4.90,1.50] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=57 FAILED [class=2, true class=1] features=(6.30,3.30,4.70,1.60] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=62 FAILED [class=2, true class=1] features=(5.90,3.00,4.20,1.50] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=65 FAILED [class=2, true class=1] features=(5.60,2.90,3.60,1.30] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=66 FAILED [class=2, true class=1] features=(6.70,3.10,4.40,1.40] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=67 FAILED [class=2, true class=1] features=(5.60,3.00,4.50,1.50] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=76 FAILED [class=2, true class=1] features=(6.60,3.00,4.40,1.40] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=79 FAILED [class=2, true class=1] features=(6.00,2.90,4.50,1.50] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=86 FAILED [class=2, true class=1] features=(6.00,3.40,4.50,1.60] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=87 FAILED [class=2, true class=1] features=(6.70,3.10,4.70,1.50] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=89 FAILED [class=2, true class=1] features=(5.60,3.00,4.10,1.30] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=92 FAILED [class=2, true class=1] features=(6.10,3.00,4.60,1.40] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=109 FAILED [class=1, true class=2] features=(6.70,2.50,5.80,1.80] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV correct results: 85.33% Iris_RidgeClassifierCV (EURUSD,H1) model=RidgeClassifierCV all samples accuracy=0.853333 Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV FAILED [class=2, true class=1] features=(7.00,3.20,4.70,1.40) Iris_RidgeClassifierCV (EURUSD,H1) model:RidgeClassifierCV FAILED [class=2, true class=1] features=(6.40,3.20,4.50,1.50) Iris_RidgeClassifierCV (EURUSD,H1) model=RidgeClassifierCV batch test accuracy=0.000000
ONNX modelinin performansı, orijinal scikit-learn modelinin performansıyla mükemmel bir şekilde eşleşmektedir (%85.33).
2.6.3. RidgeClassifierCV modelinin ONNX gösterimi
Şekil 20. Netron'da RidgeClassifierCV modelinin ONNX gösterimi
2.7. Random Forest Classifier
Random Forest Classifier, birden fazla karar ağacı oluşturmaya ve sınıflandırma kalitesini artırmak için sonuçlarını birleştirmeye dayanan bir topluluk makine öğrenimi yöntemidir. Bu yöntem, etkinliği ve farklı verilerle çalışma kabiliyeti nedeniyle son derece popülerdir.
Random Forest Classifier’ın prensipleri:
- Bagging (Bootstrap Aggregating): Random Forest, eğitim verilerinden değiştirme ile birden fazla alt örneklem (yeniden örnekleme) oluşturmayı içeren torbalama yöntemini kullanır. Her bir alt örneklem için ayrı bir karar ağacı oluşturulur.
- Rastgele özellik seçimi: Her bir ağaç oluşturulurken, tüm özellik kümesinden rastgele bir özellik alt kümesi seçilir. Bu, ağaçlar arasında çeşitliliği teşvik eder ve aralarındaki korelasyonları azaltır.
- Oylama: Bir nesneyi sınıflandırırken, her ağaç kendi tahminini sunar ve tüm ağaçlar arasında en çok oyu alan sınıf nihai model tahmini olarak seçilir.
Random Forest Classifier’ın avantajları:
- Yüksek doğruluk: Random Forest tipik olarak birden fazla ağacın sonuçlarının ortalamasını alarak yüksek sınıflandırma doğruluğuna ulaşır.
- Farklı verileri işleme becerisi: Sayısal ve kategorik özelliklerin yanı sıra farklı yapılardaki verilerle de iyi çalışır.
- Aşırı uyum direnci: Random Forest yerleşik düzenlileştirmeye sahiptir, bu da onu aşırı uyuma karşı dirençli hale getirir.
- Özelliğin önemi: Random Forest, özelliklerin önemini değerlendirerek veri bilimcilerin ve özellik mühendislerinin verileri daha iyi anlamasına yardımcı olabilir.
Random Forest Classifier’ın sınırlamaları:
- Hesaplama karmaşıklığı: Bir Random Forest’ı eğitmek, özellikle çok sayıda ağaç ve özellik söz konusu olduğunda zaman alıcı olabilir.
- Yorumlanabilirlik zorlukları: Çok sayıda ağaç ve rastgele özellik seçimi nedeniyle modelin yorumlanması zor olabilir.
- Aykırı değer dayanıklılığı garanti edilmez: Random Forest, veri aykırı değerlerine karşı her zaman dayanıklılık sağlamaz.
Random Forest Classifier, biyotıp, finansal analiz ve metin veri analizi dahil olmak üzere çeşitli alanlarda yaygın olarak kullanılan güçlü bir makine öğrenimi algoritmasıdır. Sınıflandırma ve regresyon görevlerini çözmede başarılıdır ve yüksek genelleme kabiliyetine sahiptir.
2.7.1. Random Forest Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Random Forest Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_RandomForestClassifier.py # The code demonstrates the process of training Random Forest Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023,2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Random Forest Classifier model rf_model = RandomForestClassifier(n_estimators=100, random_state=42) # train the model on the entire dataset rf_model.fit(X, y) # predict classes for the entire dataset y_pred = rf_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Random Forest Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(rf_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "rf_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Random Forest Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 1.00 1.00 50
Python 2 1.00 1.00 1.00 50
Python
Python accuracy 1.00 150
Python macro avg 1.00 1.00 1.00 150
Python weighted avg 1.00 1.00 1.00 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\rf_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Random Forest Classifier model in ONNX format: 1.0
Random Forest Classifier modeli (ve ONNX versiyonu) Fisher'ın iris sınıflandırma problemini %100 doğrulukla çözmektedir.
2.7.2. Random Forest Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_RandomForestClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "rf_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="RandomForestClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_RandomForestClassifier (EURUSD,H1) model:RandomForestClassifier correct results: 100.00% Iris_RandomForestClassifier (EURUSD,H1) model=RandomForestClassifier all samples accuracy=1.000000 Iris_RandomForestClassifier (EURUSD,H1) model=RandomForestClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %100'dür ve bu da orijinal modelin doğruluğuyla eşleşmektedir.
2.7.3. Random Forest Classifier modelinin ONNX gösterimi
Şekil 21. Netron'da Random Forest Classifier modelinin ONNX gösterimi
2.8. Gradient Boosting Classifier
Gradyan artırma, en güçlü makine öğrenimi yöntemlerinden biridir ve yüksek doğruluğu ve farklı verilerle çalışma yeteneği sayesinde veri analizi, bilgisayarlı görme, doğal dil işleme ve finansal analiz dahil olmak üzere çok çeşitli alanlarda uygulama alanı bulur. Gradient Boosting Classifier, sınıflandırma görevlerini çözmek için karar ağaçlarının bir bileşimini oluşturan bir topluluk makine öğrenimi yöntemidir. Bu yöntem, yüksek doğruluk elde etme kabiliyeti ve aşırı uyuma karşı direnci nedeniyle popülerdir.
Gradient Boosting Classifier’ın prensipleri:
- Karar ağaçları topluluğu: Gradient Boosting Classifier, her ağacın bir önceki ağacın tahminlerini iyileştirmeyi amaçladığı bir karar ağaçları topluluğu oluşturur.
- Gradyan iniş: Gradyan artırma, kayıp fonksiyonunu optimize etmek için gradyan inişi kullanır. Kayıp fonksiyonunun gradyanını hesaplayarak ve tahminleri bu gradyana göre güncelleyerek sınıflandırma hatasını en aza indirir.
- Ağaç ağırlıklandırma: Bileşimdeki her ağacın bir ağırlığı vardır ve sonunda tüm ağaçlardan gelen tahminler ağırlıkları dikkate alınarak birleştirilir.
Gradient Boosting Classifier’ın avantajları:
- Yüksek doğruluk: Gradient Boosting Classifier tipik olarak yüksek sınıflandırma doğruluğu sağlar ve en güçlü makine öğrenimi yöntemlerinden biridir.
- Aşırı uyum direnci: Düzenlileştirme ve gradyan iniş kullanımı sayesinde bu yöntem, özellikle hiperparametreler ayarlanırken aşırı uyuma karşı dirençlidir.
- Farklı veri tipleriyle çalışabilme becerisi: Gradient Boosting Classifier, sayısal ve kategorik özellikler dahil olmak üzere çeşitli veri türlerini işleyebilir.
Gradient Boosting Classifier’ın sınırlamaları:
- Hesaplama karmaşıklığı: Gradient Boosting Classifier’ı eğitmek, özellikle çok sayıda ağaç veya derin ağaçlar söz konusu olduğunda hesaplama açısından yoğun olabilir.
- Yorumlanabilirlik zorlukları: Birden fazla ağacın bileşiminin karmaşıklığı nedeniyle, sonuçları yorumlamak zor olabilir.
- Küçük veri kümeleri için her zaman uygun değildir: Gradyan artırma genellikle etkili çalışma için önemli miktarda veri gerektirir ve küçük veri kümelerinde aşırı uyuma eğilimli olabilir.
Gradient Boosting Classifier, veri analizi yarışmalarında sıklıkla kullanılan ve çeşitli sınıflandırma görevlerini etkili bir şekilde çözen güçlü bir makine öğrenimi yöntemidir. Verilerdeki karmaşık doğrusal olmayan ilişkileri keşfedebilir ve hiperparametreler uygun şekilde ayarlandığında iyi bir genelleme sergiler.
2.8.1. Gradient Boosting Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Gradient Boosting Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_GradientBoostingClassifier.py # The code demonstrates the process of training Gradient Boostring Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.ensemble import GradientBoostingClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Gradient Boosting Classifier model gb_model = GradientBoostingClassifier(n_estimators=100, random_state=42) # train the model on the entire dataset gb_model.fit(X, y) # predict classes for the entire dataset y_pred = gb_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Gradient Boosting Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(gb_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "gb_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Gradient Boosting Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 1.00 1.00 50
Python 2 1.00 1.00 1.00 50
Python
Python accuracy 1.00 150
Python macro avg 1.00 1.00 1.00 150
Python weighted avg 1.00 1.00 1.00 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\gb_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Gradient Boosting Classifier model in ONNX format: 1.0
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %100'dür ve bu da orijinal modelin doğruluğuyla eşleşmektedir.
2.8.2. Gradient Boosting Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_GradientBoostingClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "gb_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="GradientBoostingClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_GradientBoostingClassifier (EURUSD,H1) model:GradientBoostingClassifier correct results: 100.00% Iris_GradientBoostingClassifier (EURUSD,H1) model=GradientBoostingClassifier all samples accuracy=1.000000 Iris_GradientBoostingClassifier (EURUSD,H1) model=GradientBoostingClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %100'dür ve bu da orijinal modelin doğruluğuyla eşleşmektedir.
2.8.3. Gradient Boosting Classifier modelinin ONNX gösterimi
Şekil 22. Netron'da Gradient Boosting Classifier modelinin ONNX gösterimi
2.9. Adaptive Boosting Classifier
AdaBoost (Adaptive Boosting) Classifier, daha güçlü bir algoritma oluşturmak için birden fazla zayıf (örneğin karar ağaçları) sınıflandırıcının sonuçlarını birleştirerek sınıflandırmayı geliştirmek için kullanılan bir topluluk makine öğrenimi yöntemidir.
AdaBoost Classifier’ın prensipleri:
- Zayıf sınıflandırıcılar topluluğu: AdaBoost, eğitim setindeki her bir örneklemin ağırlıklarını eşit başlangıç değerleri atayarak başlatır.
- Zayıf sınıflandırıcıları eğitme: AdaBoost daha sonra örneklem ağırlıklarını dikkate alarak eğitim seti üzerinde zayıf bir sınıflandırıcıyı (örneğin bir karar ağacı) eğitir. Bu sınıflandırıcı örneklemleri doğru bir şekilde sınıflandırmaya çalışır.
- Ağırlık yeniden dağıtımı: AdaBoost, yanlış sınıflandırılmış örneklemlerin ağırlıklarını artırarak ve doğru sınıflandırılmış örneklerin ağırlıklarını azaltarak örnek ağırlıklarını ayarlar.
- Bileşim oluşturma: AdaBoost, zayıf sınıflandırıcıları eğitme ve ağırlıkları yeniden dağıtma işlemini birçok kez tekrarlar. Bu zayıf sınıflandırıcıların sonuçları daha sonra her sınıflandırıcının doğruluğuna göre katkıda bulunduğu bir bileşimde birleştirilir.
AdaBoost Classifier’ın avantajları:
- Yüksek doğruluk: AdaBoost tipik olarak birkaç zayıf sınıflandırıcıyı birleştirerek yüksek sınıflandırma doğruluğu sağlar.
- Aşırı uyum direnci: AdaBoost yerleşik düzenlileştirmeye sahiptir, bu da onu aşırı uyuma karşı dirençli hale getirir.
- Çeşitli sınıflandırıcılarla çalışabilme becerisi: AdaBoost farklı temel sınıflandırıcılar kullanabilir ve böylece belirli görevlere uyarlanabilir.
AdaBoost Classifier’ın sınırlamaları:
- Aykırı değerlere hassasiyet: AdaBoost, önemli bir ağırlığa sahip olabilecekleri için verilerdeki aykırı değerlere karşı hassas olabilir.
- Karmaşık görevler için her zaman uygun değildir: Bazı karmaşık görevlerde, AdaBoost iyi sonuçlar elde etmek için çok sayıda temel sınıflandırıcı gerektirebilir.
- Temel sınıflandırıcıların kalitesine bağımlılık: AdaBoost, temel sınıflandırıcılar rastgele tahminden daha iyi olduğunda daha iyi performans gösterir.
AdaBoost Classifier, sınıflandırma görevlerini çözmek için pratikte yaygın olarak kullanılan güçlü bir makine öğrenimi algoritmasıdır. Hem ikili hem de çok sınıflı problemler için çok uygundur ve çeşitli temel sınıflandırıcılara uyarlanabilir.
2.9.1. Adaptive Boosting Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Adaptive Boosting Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_AdaBoostClassifier.py # The code demonstrates the process of training AdaBoost Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.ensemble import AdaBoostClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 an AdaBoost Classifier model adaboost_model = AdaBoostClassifier(n_estimators=50, random_state=42) # train the model on the entire dataset adaboost_model.fit(X, y) # predict classes for the entire dataset y_pred = adaboost_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of AdaBoost Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(adaboost_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "adaboost_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of AdaBoost Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.92 0.96 0.94 50
Python 2 0.96 0.92 0.94 50
Python
Python accuracy 0.96 150
Python macro avg 0.96 0.96 0.96 150
Python weighted avg 0.96 0.96 0.96 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\adaboost_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of AdaBoost Classifier model in ONNX format: 0.96
2.9.2. Adaptive Boosting Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_AdaBoostClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "adaboost_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="AdaBoostClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_AdaBoostClassifier (EURUSD,H1) model:AdaBoostClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AdaBoostClassifier (EURUSD,H1) model:AdaBoostClassifier sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AdaBoostClassifier (EURUSD,H1) model:AdaBoostClassifier sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_AdaBoostClassifier (EURUSD,H1) model:AdaBoostClassifier sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AdaBoostClassifier (EURUSD,H1) model:AdaBoostClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AdaBoostClassifier (EURUSD,H1) model:AdaBoostClassifier sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_AdaBoostClassifier (EURUSD,H1) model:AdaBoostClassifier correct results: 96.00% Iris_AdaBoostClassifier (EURUSD,H1) model=AdaBoostClassifier all samples accuracy=0.960000 Iris_AdaBoostClassifier (EURUSD,H1) model=AdaBoostClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %96'dır ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.9.3. Adaptive Boosting Classifier modelinin ONNX gösterimi
Şekil 23. Netron'da Adaptive Boosting Classifier modelinin ONNX gösterimi
2.10. Bootstrap Aggregating Classifier
Bagging (Bootstrap Aggregating) Classifier, eğitim verisinden birden fazla rastgele alt örneklem (yeniden örnekleme) oluşturmaya ve her biri üzerinde ayrı modeller oluşturmaya dayanan bir topluluk makine öğrenimi yöntemidir. Sonuçlar daha sonra modelin genelleme yeteneğini geliştirmek için birleştirilir.
Bagging Classifier’ın prensipleri:
- Alt örneklemler oluşturma: Bagging, eğitim verisinden değiştirme ile birkaç rastgele alt örneklem (yeniden örnekleme) oluşturarak başlar. Bu da aynı örneklemlerin birden fazla alt örneklemde yer alabileceği ve bazı örneklemlerin atlanabileceği anlamına gelir.
- Temel modelleri eğitme: Her bir alt örneklem üzerinde ayrı bir temel model (örneğin bir karar ağacı) eğitilir. Her model diğerlerinden bağımsız olarak eğitilir.
- Sonuçların birleştirilmesi: Tüm temel modeller eğitildikten sonra, tahminlerinin sonuçları nihai tahmini elde etmek için birleştirilir. İkili sınıflandırmada bu, çoğunluk oylaması yoluyla yapılabilir.
Bagging Classifier’ın avantajları:
- Düşük varyans: Bagging, birden fazla temel modelin sonuçlarının ortalamasını alarak modelin varyansını azaltır, bu da daha istikrarlı ve güvenilir tahminlere yol açabilir.
- Aşırı uyum azaltma: Her bir temel model farklı alt örneklemler üzerinde eğitildiğinden, Bagging modelin aşırı uyum eğilimini azaltabilir.
- Çok yönlülük: Bagging, farklı veri türlerine ve görevlere uyarlanmaya olanak tanıyan çeşitli temel modeller kullanabilir.
Bagging Classifier’ın sınırlamaları:
- Yanlılığı iyileştirmez: Bagging varyansı azaltma eğilimindedir ancak modelin yanlılığını çözmez. Temel modeller yanlı olma eğilimindeyse (örneğin, yetersiz uyum), Bagging bu sorunu düzeltmeyecektir.
- Karmaşık görevler için her zaman uygun değildir: Bazı karmaşık görevlerde, Bagging iyi sonuçlar elde etmek için çok sayıda temel model gerektirebilir.
Bagging Classifier, modelin genelleme yeteneğini artırabilen ve aşırı uyumu azaltabilen etkili bir makine öğrenimi yöntemidir. Çeşitli sınıflandırma ve regresyon görevlerini ele almak için genellikle farklı temel modellerle birlikte kullanılır.
2.10.1. Bootstrap Aggregating Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Bootstrap Aggregating Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_BootstrapAggregatingClassifier.py # The code demonstrates the process of training Bagging Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.ensemble import BaggingClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Bagging Classifier model with a Decision Tree base estimator bagging_model = BaggingClassifier(n_estimators=100, random_state=42) # train the model on the entire dataset bagging_model.fit(X, y) # predict classes for the entire dataset y_pred = bagging_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Bagging Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(bagging_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "bagging_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Bagging Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 1.00 1.00 50
Python 2 1.00 1.00 1.00 50
Python
Python accuracy 1.00 150
Python macro avg 1.00 1.00 1.00 150
Python weighted avg 1.00 1.00 1.00 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\bagging_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Bagging Classifier model in ONNX format: 1.0
Bootstrap Aggregating Classifier modeli (ve ONNX versiyonu) iris veri setini sınıflandırmada %100 doğruluk elde etmiştir.
2.10.2. Bootstrap Aggregating Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_BootstrapAggregatingClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "bagging_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="BootstrapAggregatingClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_BootstrapAggregatingClassifier (EURUSD,H1) model:BootstrapAggregatingClassifier correct results: 100.00% Iris_BootstrapAggregatingClassifier (EURUSD,H1) model=BootstrapAggregatingClassifier all samples accuracy=1.000000 Iris_BootstrapAggregatingClassifier (EURUSD,H1) model=BootstrapAggregatingClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri setindeki doğruluğu %100'dür ve bu da orijinal modelin doğruluğu ile tutarlıdır.
2.10.3. Bootstrap Aggregating Classifier modelinin ONNX gösterimi
Şekil 24. Netron'da Bootstrap Aggregating Classifier modelinin ONNX gösterimi
2.11. K-Nearest Neighbors (K-NN) Classifier
K-Nearest Neighbors (K-NN) Classifier, veri noktaları arasındaki benzerliğe dayalı sınıflandırma ve regresyon görevlerini çözmek için kullanılan bir makine öğrenimi yöntemidir. Çok boyutlu bir özellik uzayında birbirine yakın nesnelerin benzer karakteristiğe sahip olduğu ve bu nedenle benzer sınıf etiketlerine sahip olabileceği ilkesine göre çalışır.
K-NN Classifier’ın prensipleri:
- Yakınlığın belirlenmesi: K-NN Classifier, sınıflandırılacak nesne ile eğitim veri kümesindeki diğer nesneler arasındaki yakınlığı hesaplar. Bu genellikle Öklid mesafesi veya Manhattan mesafesi gibi bir mesafe metriği kullanılarak yapılır.
- Komşu sayısının seçilmesi: K parametresi, bir nesneyi sınıflandırmak için kullanılacak en yakın komşu sayısını belirler. Tipik olarak K, göreve ve verilere göre seçilir.
- Oylama: K-NN, nesnenin sınıfını belirlemek için en yakın K komşu arasında çoğunluk oylamasını kullanır. Örneğin, K komşunun çoğunluğu A sınıfına aitse, nesne de A sınıfı olarak sınıflandırılacaktır.
K-NN Classifier’ın avantajları:
- Basitlik ve sezgisellik: K-NN, anlaşılması ve uygulanması kolay, basit ve sezgisel bir yöntemdir.
- Farklı veri tipleriyle çalışabilme becerisi: K-NN, sayısal, kategorik ve metin verileri dahil olmak üzere çeşitli veri türleri için kullanılabilir.
- Değişen verilere uyarlanabilirlik: K-NN, verilerdeki değişikliklere hızlı bir şekilde adapte olabilir, bu da onu dinamik verilere sahip görevler için uygun hale getirir.
K-NN Classifier’ın sınırlamaları:
- K seçimine duyarlılık: Optimum K değerini seçmek basit olmayan bir görev olabilir. Küçük bir K aşırı uyuma yol açabilirken, büyük bir K yetersiz uyuma yol açabilir.
- Özellik ölçeklendirmesine duyarlılık. K-NN özellik ölçeklendirmesine duyarlıdır, bu nedenle veri normalizasyonu önemli olabilir.
- Hesaplama karmaşıklığı: Büyük veri kümeleri ve çok sayıda özellik için, tüm nesne çiftleri arasındaki mesafeleri hesaplamak hesaplama açısından maliyetli olabilir.
- Yorumlanabilirlik eksikliği: K-NN sonuçlarını yorumlamak, özellikle K büyük olduğunda ve çok fazla veri olduğunda zor olabilir.
K-NN Classifier, tavsiye sistemleri, metin sınıflandırma ve örüntü tanıma gibi nesne yakınlığının önemli olduğu görevlerde yararlı olabilecek bir makine öğrenimi yöntemidir. İlk veri analizi ve hızlı model prototipleme için çok uygundur.
2.11.1. K-Nearest Neighbors (K-NN) Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir K-Nearest Neighbors (K-NN) Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_KNearestNeighborsClassifier.py # The code uses the K-Nearest Neighbors (KNN) Classifier for the Iris dataset, converts the model to ONNX format, saves it, and evaluates its accuracy. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a K-Nearest Neighbors (KNN) Classifier model knn_model = KNeighborsClassifier(n_neighbors=3) # train the model on the entire dataset knn_model.fit(X, y) # predict classes for the entire dataset y_pred = knn_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of KNN Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(knn_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "knn_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of KNN Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.94 0.94 0.94 50
Python 2 0.94 0.94 0.94 50
Python
Python accuracy 0.96 150
Python macro avg 0.96 0.96 0.96 150
Python weighted avg 0.96 0.96 0.96 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\knn_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of KNN Classifier model in ONNX format: 0.96
2.11.2. K-Nearest Neighbors (K-NN) Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_KNearestNeighborsClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "knn_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="KNearestNeighborsClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_KNearestNeighborsClassifier (EURUSD,H1) model:KNearestNeighborsClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_KNearestNeighborsClassifier (EURUSD,H1) model:KNearestNeighborsClassifier sample=73 FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50] Iris_KNearestNeighborsClassifier (EURUSD,H1) model:KNearestNeighborsClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_KNearestNeighborsClassifier (EURUSD,H1) model:KNearestNeighborsClassifier sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_KNearestNeighborsClassifier (EURUSD,H1) model:KNearestNeighborsClassifier sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_KNearestNeighborsClassifier (EURUSD,H1) model:KNearestNeighborsClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_KNearestNeighborsClassifier (EURUSD,H1) model:KNearestNeighborsClassifier correct results: 96.00% Iris_KNearestNeighborsClassifier (EURUSD,H1) model=KNearestNeighborsClassifier all samples accuracy=0.960000 Iris_KNearestNeighborsClassifier (EURUSD,H1) model:KNearestNeighborsClassifier FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50) Iris_KNearestNeighborsClassifier (EURUSD,H1) model=KNearestNeighborsClassifier batch test accuracy=0.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %96'dır ve bu da orijinal modelin doğruluğu ile tutarlıdır.
2.11.3. K-Nearest Neighbors (K-NN) Classifier modelinin ONNX gösterimi
Şekil 25. Netron'da K-Nearest Neighbors Classifier modelinin ONNX gösterimi
2.12. Decision Tree Classifier
Decision Tree Classifier, bir karar ağacının oluşturulmasına dayanan sınıflandırma görevleri için kullanılan bir makine öğrenimi yöntemidir. Bu yöntem, özellikler üzerinde bir dizi koşullu test gerçekleştirerek veri kümesini daha küçük alt gruplara ayırır ve bir nesnenin sınıfını ağaçta izlediği yola göre belirler.
Decision Tree Classifier’ın prensipleri:
- Karar ağacının oluşturulması: Başlangıçta, tüm veriler ağacın kökünde temsil edilir. Ağacın her bir düğümü için veriler, her bir alt gruptaki belirsizliği (örneğin entropi veya Gini endeksi) en aza indirmeyi amaçlayan bir özelliğin değerlerine dayalı olarak iki veya daha fazla alt gruba ayrılır.
- Yinelemeli inşa: Verileri bölme işlemi, ağaç yapraklarına ulaşana kadar yinelemeli olarak gerçekleştirilir. Yapraklar nesnelerin nihai sınıflarını temsil eder.
- Karar verme: Bir nesne ağaca girdiğinde, kökten yapraklardan birine doğru bir yol izler ve burada sınıfı o yapraktaki nesnelerin çoğunluğuna göre belirlenir.
Decision Tree Classifier’ın avantajları:
- Yorumlanabilirlik: Karar ağaçlarının yorumlanması ve görselleştirilmesi kolaydır. Sınıflandırma için kullanılan karar kuralları anlaşılabilirdir.
- Farklı veri türlerini işleme: Decision Tree Classifier hem sayısal hem de kategorik özelliklerle çalışabilir.
- Özelliğin önemi: Karar ağaçları, özelliklerin önemini değerlendirerek veri analistlerinin ve özellik mühendislerinin verileri anlamasına yardımcı olabilir.
Decision Tree Classifier’ın sınırlamaları:
- Aşırı uyum: Büyük ve derin ağaçlar aşırı uyum sağlamaya eğilimli olabilir, bu da onları yeni verilere daha az genelleştirilebilir hale getirir.
- Gürültüye karşı hassasiyet: Karar ağaçları, verilerdeki gürültü ve aykırı değerlere karşı hassas olabilir.
- Açgözlü inşa: Karar ağaçları açgözlü bir algoritma kullanılarak oluşturulur ve bu da optimum olmayan global çözümlere yol açabilir.
- Veri değişikliklerine karşı istikrarsızlık: Verilerdeki küçük değişiklikler ağaç yapısında önemli değişikliklere yol açabilir.
Decision Tree Classifier, özellikle modelin yorumlanabilirliğinin önemli olduğu ve hangi özelliklerin kararı etkilediğini anlamanız gereken durumlarda, sınıflandırma görevleri için yararlı bir makine öğrenimi yöntemidir. Bu yöntem, Random Forest ve Gradient Boosting gibi topluluk yöntemlerinde de kullanılabilir.
2.12.1. Decision Tree Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Decision Tree Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_DecisionTreeClassifier.py # The code uses the Decision Tree Classifier for the Iris dataset, converts the model to ONNX format, saves it, and evaluates its accuracy. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Decision Tree Classifier model decision_tree_model = DecisionTreeClassifier(random_state=42) # train the model on the entire dataset decision_tree_model.fit(X, y) # predict classes for the entire dataset y_pred = decision_tree_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Decision Tree Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(decision_tree_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "decision_tree_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Decision Tree Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 1.00 1.00 50
Python 2 1.00 1.00 1.00 50
Python
Python accuracy 1.00 150
Python macro avg 1.00 1.00 1.00 150
Python weighted avg 1.00 1.00 1.00 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\decision_tree_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Decision Tree Classifier model in ONNX format: 1.0
Decision Tree Classifier modeli (ve ONNX versiyonu) Fisher'ın iris veri setinin tamamını sınıflandırmada %100 doğruluk göstermiştir.
2.12.2. Decision Tree Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_DecisionTreeClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "decision_tree_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="DecisionTreeClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_DecisionTreeClassifier (EURUSD,H1) model:DecisionTreeClassifier correct results: 100.00% Iris_DecisionTreeClassifier (EURUSD,H1) model=DecisionTreeClassifier all samples accuracy=1.000000 Iris_DecisionTreeClassifier (EURUSD,H1) model=DecisionTreeClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %100'dür ve bu da orijinal modelin doğruluğuyla eşleşmektedir.
2.12.3. Decision Tree Classifier modelinin ONNX gösterimi
Şekil 26. Netron'da Decision Tree Classifier modelinin ONNX gösterimi
LogisticRegression ve LogisticRegressionCV hakkında not:
LogisticRegression ve LogisticRegressionCV, lojistik regresyon kullanarak ikili sınıflandırma için kullanılan iki sınıflandırıcıdır, ancak model parametrelerinin nasıl ayarlandığı konusunda farklılık gösterirler:
LogisticRegression:
- LogisticRegression, iki sınıftan birine ait olma olasılığını modellemek için lojistik fonksiyon kullanan bir sınıflandırıcıdır (ikili sınıflandırma).
- C (ters düzenlileştirme gücü), ceza (düzenlileştirme türü, örneğin L1 veya L2), çözücü (optimizasyon algoritması) vb. gibi özelleştirme için temel parametreler sağlar.
- LogisticRegression kullanırken, genellikle parametre değerlerini ve bunların kombinasyonlarını manuel olarak seçer ve ardından modeli veriler üzerinde eğitirsiniz.
LogisticRegressionCV:
- LogisticRegressionCV, çapraz doğrulama ve C düzenlileştirme parametresinin optimum değerinin seçilmesi için yerleşik destek sağlayan LogisticRegression'ın bir uzantısıdır.
- C'yi manuel olarak seçmek yerine, LogisticRegressionCV'ye keşfedilecek C değerlerinin bir listesini iletebilir ve çapraz doğrulama yöntemini belirtebilirsiniz (örneğin, cv parametresi aracılığıyla).
- LogisticRegressionCV, çapraz doğrulamada en iyi performansı gösteren optimum C değerini otomatik olarak seçer.
- Bu, özellikle çok fazla veriniz varsa veya hangi C değerini seçeceğinizden emin değilseniz, düzenlileştirmeyi otomatik olarak ayarlamanız gerektiğinde kullanışlıdır.
Dolayısıyla, aralarındaki temel fark parametre ayarlamasındaki otomasyon seviyesinde yatmaktadır. LogisticRegression, C değerinin manuel olarak ayarlanmasını gerektirirken LogisticRegressionCV, çapraz doğrulama yoluyla optimum C değerinin otomatik olarak seçilmesine olanak tanır. Bunlar arasındaki tercih, ihtiyaçlarınıza ve model ayarlama sürecindeki otomasyon isteğinize bağlıdır.
2.13. Logistic Regression Classifier
Logistic Regression Classifier, ikili ve çok sınıflı sınıflandırma görevleri için kullanılan bir makine öğrenimi yöntemidir. Adında "regresyon" olmasına rağmen, lojistik regresyon aslında bir nesnenin sınıflardan birine ait olma olasılığını tahmin eder. Bu olasılıklara dayanarak nihai sınıflandırma kararı verilir.
Logistic Regression Classifier’ın prensipleri:
- Olasılık tahmini: Lojistik regresyon, lojistik (sigmoid) fonksiyon kullanarak bir nesnenin belirli bir sınıfa ait olma olasılığını modeller.
- Karar sınırı: Tahmin edilen olasılıklara dayanarak, lojistik regresyon sınıfları ayıran karar sınırını belirler. Olasılık belirli bir eşiği (tipik olarak 0.5) aşarsa, nesne bir sınıfta sınıflandırılır; aksi takdirde, başka bir sınıfta sınıflandırılır.
- Parametre öğrenme: Lojistik regresyon modeli, kayıp fonksiyonunu en aza indirmek için özelliklerle ilişkili ağırlıkları (katsayıları) ayarlayarak bir eğitim veri kümesi üzerinde eğitilir.
Logistic Regression Classifier’ın avantajları:
- Basitlik ve yorumlanabilirlik: Lojistik regresyon, özelliklerin sınıf tahminleri üzerindeki etkisine ilişkin kolayca yorumlanabilir sonuçlara sahip basit bir modeldir.
- Büyük veri kümelerinde verimlilik: Lojistik regresyon, büyük veri kümelerini verimli bir şekilde işleyebilir ve bunlar üzerinde hızlı bir şekilde eğitebilir.
- Topluluk yöntemlerinde kullanım: Lojistik regresyon, istifleme gibi topluluk yöntemlerinde temel sınıflandırıcı olarak kullanılabilir.
Logistic Regression Classifier’ın sınırlamaları:
- Doğrusallık: Lojistik regresyon, özellikler ve olasılıkların logaritması arasında doğrusal bir ilişki olduğunu varsayar ve bu da karmaşık görevler için yetersiz olabilir.
- Çok sınıflı kısıtı: Orijinal haliyle lojistik regresyon ikili sınıflandırma için tasarlanmıştır, ancak çok sınıflı sınıflandırmaya genişletmek için One-vs-All (One-vs-Rest) gibi yöntemler vardır.
- Aykırı değerlere hassasiyet: Lojistik regresyon, verilerdeki aykırı değerlere karşı hassas olabilir.
Lojistik regresyon, özellikle modelin yorumlanabilirliğinin önemli olduğu ve verilerin doğrusal veya doğrusala yakın bir yapı sergilediği durumlarda, sınıflandırma görevleri için pratikte yaygın olarak kullanılan klasik bir makine öğrenimi yöntemidir. İstatistik ve tıbbi veri analizinde, faktörlerin olayların olasılığı üzerindeki etkisini değerlendirmek için de kullanılır.
2.13.1. Logistic Regression Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Logistic Regression Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_LogisticRegressionClassifier.py # The code uses the Logistic Regression Classifier for the Iris dataset, converts the model to ONNX format, saves it, and evaluates its accuracy. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Logistic Regression Classifier model logistic_regression_model = LogisticRegression(max_iter=1000, random_state=42) # train the model on the entire dataset logistic_regression_model.fit(X, y) # predict classes for the entire dataset y_pred = logistic_regression_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Logistic Regression Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(logistic_regression_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "logistic_regression_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Logistic Regression Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.98 0.94 0.96 50
Python 2 0.94 0.98 0.96 50
Python
Python accuracy 0.97 150
Python macro avg 0.97 0.97 0.97 150
Python weighted avg 0.97 0.97 0.97 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\logistic_regression_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Logistic Regression Classifier model in ONNX format: 0.9733333333333334
2.13.2. Logistic Regression Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_LogisticRegressionClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "logistic_regression_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="LogisticRegressionClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+Çıktı:
Iris_LogisticRegressionClassifier (EURUSD,H1) model:LogisticRegressionClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_LogisticRegressionClassifier (EURUSD,H1) model:LogisticRegressionClassifier sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_LogisticRegressionClassifier (EURUSD,H1) model:LogisticRegressionClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_LogisticRegressionClassifier (EURUSD,H1) model:LogisticRegressionClassifier sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_LogisticRegressionClassifier (EURUSD,H1) model:LogisticRegressionClassifier correct results: 97.33% Iris_LogisticRegressionClassifier (EURUSD,H1) model=LogisticRegressionClassifier all samples accuracy=0.973333 Iris_LogisticRegressionClassifier (EURUSD,H1) model=LogisticRegressionClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %97.33'tür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.13.3. Logistic Regression Classifier modelinin ONNX gösterimi
Şekil 27. Netron'da Logistic Regression Classifier modelinin ONNX gösterimi
2.14. LogisticRegressionCV Classifier
LogisticRegressionCV (çapraz doğrulamalı lojistik regresyon) ikili sınıflandırma için güçlü ve esnek bir yöntemdir. Bu yöntem yalnızca lojistik regresyona dayalı sınıflandırma modelleri oluşturmanıza izin vermekle kalmaz, aynı zamanda en iyi performansı elde etmek için parametreleri otomatik olarak ayarlar.
LogisticRegressionCV’nin çalışma prensipleri:
- Lojistik regresyon: LogisticRegressionCV temel olarak lojistik regresyona dayanır. Lojistik regresyon, bir nesnenin iki sınıftan birine ait olma olasılığını modellemek için kullanılan istatistiksel bir yöntemdir. Bu model, bağımlı değişkenin ikili (iki sınıflı) olduğu veya ikiliye dönüştürülebildiği durumlarda uygulanır.
- Çapraz doğrulama: LogisticRegressionCV'nin en önemli avantajı dahili çapraz doğrulamadır. Bu, C düzenlileştirme parametresi için en uygun değeri manuel olarak seçmek yerine, yöntemin otomatik olarak farklı C değerlerini denediği ve çapraz doğrulamada en iyi performansı göstereni seçtiği anlamına gelir.
- Optimum C'yi seçme: LogisticRegressionCV, modelin performansını farklı C değerlerinde değerlendirmek için bir çapraz doğrulama stratejisi kullanır. C, model düzenlileştirmenin kapsamını kontrol eden düzenlileştirme parametresidir. Küçük bir C değeri güçlü düzenlileştirmeye işaret ederken, büyük bir C değeri zayıf düzenlileştirmeye işaret eder. Çapraz doğrulama, yetersiz uyum ve aşırı uyumu dengelemek için en uygun C değerinin seçilmesine yardımcı olur.
- Düzenlileştirme: LogisticRegressionCV ayrıca L1 (lasso) ve L2 (ridge) düzenlileştirme dahil olmak üzere çeşitli düzenlileştirme türlerini de destekler. Bu düzenlileştirme türleri, modelin genellemesini iyileştirmeye ve aşırı uyumu önlemeye yardımcı olur.
LogisticRegressionCV'nin avantajları:
Otomatik parametre ayarlama: LogisticRegressionCV'nin başlıca avantajlarından biri, çapraz doğrulama kullanarak en uygun C değerini otomatik olarak seçebilmesidir. Bu, manuel model ayarlama ihtiyacını ortadan kaldırır ve verilere ve göreve odaklanmanızı sağlar.
Aşırı uyum dayanıklılığı: LogisticRegressionCV tarafından desteklenen düzenlileştirme, modelin karmaşıklığını kontrol etmeye yardımcı olur ve özellikle sınırlı verilerle aşırı uyum riskini azaltır.
Şeffaflık: Lojistik regresyon yorumlanabilir bir yöntemdir. Her bir özelliğin tahmine katkısını analiz edebilirsiniz, bu da özelliğin önemini anlamak için yararlıdır.
Yüksek performans: Lojistik regresyon, özellikle büyük hacimli verilerle hızlı ve verimli bir şekilde çalışabilir.
LogisticRegressionCV’nin sınırlamaları:
Doğrusal bağımlılıklar: LogisticRegressionCV doğrusal ve doğrusala yakın sınıflandırma problemlerini çözmek için uygundur. Özellikler ve hedef değişken arasındaki ilişki yüksek oranda doğrusal değilse, model iyi performans göstermeyebilir.
Çok sayıda özelliğin işlenmesi: Çok sayıda özellik ile lojistik regresyon, aşırı uyumu önlemek için önemli miktarda veri veya boyut azaltma teknikleri gerektirebilir.
Veri temsili bağımlılığı: Lojistik regresyonun etkinliği, verilerin nasıl temsil edildiğine ve hangi özelliklerin seçildiğine bağlı olabilir.
LogisticRegressionCV, otomatik parametre ayarlama ve aşırı uyum sağlamlığı ile ikili sınıflandırma için güçlü bir araçtır. Özellikle hızlı bir şekilde yorumlanabilir bir sınıflandırma modeli oluşturmanız gerektiğinde kullanışlıdır. Ancak, verilerin doğrusal veya doğrusala yakın bağımlılıklar sergilediği durumlarda en iyi performansı gösterdiğini unutmamak önemlidir.
2.14.1. LogisticRegressionCV Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir LogisticRegressionCV Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_LogisticRegressionCVClassifier.py # The code demonstrates the process of training LogisticRegressionCV model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.linear_model import LogisticRegressionCV from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a LogisticRegressionCV model logistic_regression_model = LogisticRegressionCV(cv=5, max_iter=1000) # train the model on the entire dataset logistic_regression_model.fit(X, y) # predict classes for the entire dataset y_pred = logistic_regression_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of LogisticRegressionCV model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(logistic_regression_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "logistic_regressioncv_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of LogisticRegressionCV model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.98 0.96 0.97 50
Python 2 0.96 0.98 0.97 50
Python
Python accuracy 0.98 150
Python macro avg 0.98 0.98 0.98 150
Python weighted avg 0.98 0.98 0.98 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\logistic_regression_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of LogisticRegressionCV model in ONNX format: 0.98
2.14.2. LogisticRegressionCV Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_LogisticRegressionCVClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "logistic_regressioncv_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="LogisticRegressionCVClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_LogisticRegressionCVClassifier (EURUSD,H1) model:LogisticRegressionCVClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_LogisticRegressionCVClassifier (EURUSD,H1) model:LogisticRegressionCVClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_LogisticRegressionCVClassifier (EURUSD,H1) model:LogisticRegressionCVClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_LogisticRegressionCVClassifier (EURUSD,H1) model:LogisticRegressionCVClassifier correct results: 98.00% Iris_LogisticRegressionCVClassifier (EURUSD,H1) model=LogisticRegressionCVClassifier all samples accuracy=0.980000 Iris_LogisticRegressionCVClassifier (EURUSD,H1) model=LogisticRegressionCVClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %98'dir ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.14.3. LogisticRegressionCV Classifier modelinin ONNX gösterimi
Şekil 28. Netron'da LogisticRegressionCV Classifier modelinin ONNX gösterimi
2.15. Passive-Aggressive (PA) Classifier
Passive-Aggressive (PA) Classifier, sınıflandırma görevleri için kullanılan bir makine öğrenimi yöntemidir. Bu yöntemin ana fikri, sınıflandırma hatalarını en aza indirmek için eğitim sırasında modelin ağırlıklarını (katsayılarını) uyarlamaktır. Passive-Aggressive Classifier, çevrimiçi öğrenme senaryolarında ve verilerin zaman içinde değiştiği durumlarda faydalı olabilir.
Passive-Aggressive Classifier’ın çalışma prensipleri:
- Ağırlık uyarlaması: Passive-Aggressive Classifier, stokastik gradyan inişte olduğu gibi modelin ağırlıklarını kayıp fonksiyonunu en aza indirme yönünde güncellemek yerine, ağırlıkları mevcut örnek için sınıflandırma hatasını en aza indiren yönde uyarlar.
- Agresifliği sürdürme: Yöntem, modelin ağırlıklarının ne kadar güçlü bir şekilde uyarlanması gerektiğini belirleyen agresiflik (C) adlı bir parametreye sahiptir. Daha büyük C değerleri yöntemi uyarlamada daha agresif hale getirirken, daha küçük değerler daha az agresif hale getirir.
Passive-Aggressive Classifier’ın avantajları:
- Çevrimiçi öğrenme için uygundur: Passive-Aggressive Classifier yeni veriler geldikçe güncellenebilir, bu da onu verilerin bir akış halinde geldiği çevrimiçi öğrenme görevleri için uygun hale getirir.
- Veri değişikliklerine uyarlanabilirlik: Yöntem, modeli yeni koşullara uyarladığı için değişen verilerle iyi performans gösterir.
Passive-Aggressive Classifier’ın sınırlamaları:
- Agresiflik parametresi seçimine duyarlılık: C agresiflik parametresi için en uygun değerin seçilmesi ayarlama gerektirebilir ve veri karakteristiğine bağlıdır.
- Karmaşık görevler için her zaman uygun değildir: Passive-Aggressive Classifier, karmaşık özellik bağımlılıklarının dikkate alınması gereken karmaşık görevlerde yüksek doğruluk sağlayamayabilir.
- Ağırlıkların yorumlanması: Bu yöntem kullanılarak elde edilen model ağırlıkları, lineer veya lojistik regresyon kullanılarak elde edilen ağırlıklara kıyasla daha az yorumlanabilir olabilir.
Passive-Aggressive Classifier, değişen verilerle sınıflandırma görevleri ve modelin yeni koşullara hızlı adaptasyonunun çok önemli olduğu durumlar için uygun bir makine öğrenimi yöntemidir. Metin veri analizi, görüntü sınıflandırma vb. görevler de dahil olmak üzere çeşitli alanlarda uygulamalar bulur.
2.15.1. Passive-Aggressive (PA) Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Passive-Aggressive (PA) Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_PassiveAgressiveClassifier.py # The code uses the Passive-Aggressive (PA) Classifier for the Iris dataset, converts the model to ONNX format, saves it, and evaluates its accuracy. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.linear_model import PassiveAggressiveClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Passive-Aggressive (PA) Classifier model pa_classifier_model = PassiveAggressiveClassifier(max_iter=1000, random_state=42) # train the model on the entire dataset pa_classifier_model.fit(X, y) # predict classes for the entire dataset y_pred = pa_classifier_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Passive-Aggressive (PA) Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(pa_classifier_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "pa_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Passive-Aggressive (PA) Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.96 0.92 0.94 50
Python 2 0.92 0.96 0.94 50
Python
Python accuracy 0.96 150
Python macro avg 0.96 0.96 0.96 150
Python weighted avg 0.96 0.96 0.96 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\pa_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Passive-Aggressive (PA) Classifier model in ONNX format: 0.96
2.15.2. Passive-Aggressive (PA) Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_PassiveAgressiveClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "pa_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="PassiveAgressiveClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_PassiveAgressiveClassifier (EURUSD,H1) model:PassiveAgressiveClassifier sample=67 FAILED [class=2, true class=1] features=(5.60,3.00,4.50,1.50] Iris_PassiveAgressiveClassifier (EURUSD,H1) model:PassiveAgressiveClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_PassiveAgressiveClassifier (EURUSD,H1) model:PassiveAgressiveClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_PassiveAgressiveClassifier (EURUSD,H1) model:PassiveAgressiveClassifier sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_PassiveAgressiveClassifier (EURUSD,H1) model:PassiveAgressiveClassifier sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_PassiveAgressiveClassifier (EURUSD,H1) model:PassiveAgressiveClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_PassiveAgressiveClassifier (EURUSD,H1) model:PassiveAgressiveClassifier correct results: 96.00% Iris_PassiveAgressiveClassifier (EURUSD,H1) model=PassiveAgressiveClassifier all samples accuracy=0.960000 Iris_PassiveAgressiveClassifier (EURUSD,H1) model=PassiveAgressiveClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %96'dır ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.15.3. Passive-Aggressive (PA) Classifier modelinin ONNX gösterimi
Şekil 29. Netron'da Passive-Aggressive (PA) Classifier modelinin ONNX gösterimi
2.16. Perceptron Classifier
Perceptron Classifier, doğrusal bir ayırıcı hiperdüzleme dayalı olarak iki sınıfı ayırmak için kullanılan doğrusal bir ikili sınıflandırıcıdır. En basit ve en eski makine öğrenimi yöntemlerinden biridir ve temel ilkesi, eğitim veri kümesi üzerinde sınıflandırma doğruluğunu en üst düzeye çıkarmak için modelin ağırlıklarını (katsayılarını) eğitmektir.
Perceptron Classifier’ın çalışma prensipleri:
- Doğrusal hiperdüzlem: Perceptron, özellik uzayında iki sınıfı ayıran doğrusal bir hiperdüzlem oluşturur. Bu hiperdüzlem, modelin ağırlıkları (katsayıları) tarafından belirlenir.
- Ağırlık eğitimi: Başlangıçta, ağırlıklar rastgele veya sıfır olarak başlatılır. Daha sonra, eğitim veri kümesindeki her nesne için, model mevcut ağırlıklara dayanarak sınıfı tahmin eder ve bir hata durumunda bunları ayarlar. Eğitim, tüm nesneler doğru sınıflandırılana veya maksimum yineleme sayısına ulaşılana kadar devam eder.
Perceptron Classifier’ın avantajları:
- Basitlik: Perceptron çok basit bir algoritmadır, anlaşılması ve uygulanması kolaydır.
- Yüksek eğitim hızı: Perceptron, özellikle büyük veri kümeleri üzerinde hızlı bir şekilde eğitilebilir ve çevrimiçi öğrenme görevlerinde kullanılabilir.
Perceptron Classifier’ın sınırlamaları:
- Doğrusal ayrılabilirlik kısıtı: Perceptron yalnızca verilerin doğrusal olarak ayrılabilir olduğu durumlarda iyi çalışır. Veriler doğrusal olarak ayrılamazsa, Perceptron yüksek doğruluk elde edemeyebilir.
- Başlangıç ağırlıklarına duyarlılık: Ağırlıkların ilk seçimi algoritmanın yakınsamasını etkileyebilir. Kötü başlangıç ağırlığı seçimleri yavaş yakınsamaya veya sınıfları doğru şekilde ayıramayan bir nörona yol açabilir.
- Olasılıkları belirleyememe: Perceptron, belirli görevler için önemli olabilecek sınıf üyeliğine ilişkin olasılık hesaplamaları sağlamaz.
Perceptron Classifier, verilerin doğrusal olarak ayrılabilir olduğu basit durumlarda yararlı olabilecek ikili sınıflandırma için temel bir algoritmadır. Çok katmanlı sinir ağları gibi daha karmaşık yöntemler için de bir temel oluşturabilir. Verilerin karmaşık yapılara sahip olduğu daha karmaşık görevlerde, lojistik regresyon veya destek vektör makineleri (SVM) gibi diğer yöntemlerin daha yüksek sınıflandırma doğruluğu sağlayabileceğini unutmamak önemlidir.
2.16.1. Perceptron Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Perceptron Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_PerceptronClassifier.py # The code demonstrates the process of training Perceptron Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.linear_model import Perceptron from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Perceptron Classifier model perceptron_model = Perceptron(max_iter=1000, random_state=42) # train the model on the entire dataset perceptron_model.fit(X, y) # predict classes for the entire dataset y_pred = perceptron_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Perceptron Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(perceptron_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "perceptron_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Perceptron Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 0.80 0.89 50
Python 1 0.46 1.00 0.63 50
Python 2 1.00 0.04 0.08 50
Python
Python accuracy 0.61 150
Python macro avg 0.82 0.61 0.53 150
Python weighted avg 0.82 0.61 0.53 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\perceptron_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Perceptron Classifier model in ONNX format: 0.6133333333333333
2.16.2. Perceptron Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_PerceptronClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "perceptron_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="PerceptronClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=2 FAILED [class=1, true class=0] features=(4.90,3.00,1.40,0.20] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=9 FAILED [class=1, true class=0] features=(4.40,2.90,1.40,0.20] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=10 FAILED [class=1, true class=0] features=(4.90,3.10,1.50,0.10] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=13 FAILED [class=1, true class=0] features=(4.80,3.00,1.40,0.10] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=21 FAILED [class=1, true class=0] features=(5.40,3.40,1.70,0.20] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=26 FAILED [class=1, true class=0] features=(5.00,3.00,1.60,0.20] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=31 FAILED [class=1, true class=0] features=(4.80,3.10,1.60,0.20] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=35 FAILED [class=1, true class=0] features=(4.90,3.10,1.50,0.20] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=42 FAILED [class=1, true class=0] features=(4.50,2.30,1.30,0.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=46 FAILED [class=1, true class=0] features=(4.80,3.00,1.40,0.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=102 FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=103 FAILED [class=1, true class=2] features=(7.10,3.00,5.90,2.10] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=104 FAILED [class=1, true class=2] features=(6.30,2.90,5.60,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=105 FAILED [class=1, true class=2] features=(6.50,3.00,5.80,2.20] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=106 FAILED [class=1, true class=2] features=(7.60,3.00,6.60,2.10] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=108 FAILED [class=1, true class=2] features=(7.30,2.90,6.30,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=109 FAILED [class=1, true class=2] features=(6.70,2.50,5.80,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=110 FAILED [class=1, true class=2] features=(7.20,3.60,6.10,2.50] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=111 FAILED [class=1, true class=2] features=(6.50,3.20,5.10,2.00] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=112 FAILED [class=1, true class=2] features=(6.40,2.70,5.30,1.90] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=113 FAILED [class=1, true class=2] features=(6.80,3.00,5.50,2.10] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=114 FAILED [class=1, true class=2] features=(5.70,2.50,5.00,2.00] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=116 FAILED [class=1, true class=2] features=(6.40,3.20,5.30,2.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=117 FAILED [class=1, true class=2] features=(6.50,3.00,5.50,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=118 FAILED [class=1, true class=2] features=(7.70,3.80,6.70,2.20] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=119 FAILED [class=1, true class=2] features=(7.70,2.60,6.90,2.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=121 FAILED [class=1, true class=2] features=(6.90,3.20,5.70,2.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=122 FAILED [class=1, true class=2] features=(5.60,2.80,4.90,2.00] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=123 FAILED [class=1, true class=2] features=(7.70,2.80,6.70,2.00] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=124 FAILED [class=1, true class=2] features=(6.30,2.70,4.90,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=125 FAILED [class=1, true class=2] features=(6.70,3.30,5.70,2.10] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=126 FAILED [class=1, true class=2] features=(7.20,3.20,6.00,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=127 FAILED [class=1, true class=2] features=(6.20,2.80,4.80,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=128 FAILED [class=1, true class=2] features=(6.10,3.00,4.90,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=129 FAILED [class=1, true class=2] features=(6.40,2.80,5.60,2.10] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=131 FAILED [class=1, true class=2] features=(7.40,2.80,6.10,1.90] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=132 FAILED [class=1, true class=2] features=(7.90,3.80,6.40,2.00] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=133 FAILED [class=1, true class=2] features=(6.40,2.80,5.60,2.20] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=136 FAILED [class=1, true class=2] features=(7.70,3.00,6.10,2.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=137 FAILED [class=1, true class=2] features=(6.30,3.40,5.60,2.40] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=138 FAILED [class=1, true class=2] features=(6.40,3.10,5.50,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=139 FAILED [class=1, true class=2] features=(6.00,3.00,4.80,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=140 FAILED [class=1, true class=2] features=(6.90,3.10,5.40,2.10] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=141 FAILED [class=1, true class=2] features=(6.70,3.10,5.60,2.40] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=142 FAILED [class=1, true class=2] features=(6.90,3.10,5.10,2.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=143 FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=144 FAILED [class=1, true class=2] features=(6.80,3.20,5.90,2.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=145 FAILED [class=1, true class=2] features=(6.70,3.30,5.70,2.50] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=146 FAILED [class=1, true class=2] features=(6.70,3.00,5.20,2.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=147 FAILED [class=1, true class=2] features=(6.30,2.50,5.00,1.90] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=148 FAILED [class=1, true class=2] features=(6.50,3.00,5.20,2.00] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=149 FAILED [class=1, true class=2] features=(6.20,3.40,5.40,2.30] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier sample=150 FAILED [class=1, true class=2] features=(5.90,3.00,5.10,1.80] Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier correct results: 61.33% Iris_PerceptronClassifier (EURUSD,H1) model=PerceptronClassifier all samples accuracy=0.613333 Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier FAILED [class=1, true class=2] features=(6.30,2.70,4.90,1.80) Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier FAILED [class=1, true class=0] features=(4.90,3.10,1.50,0.10) Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90) Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier FAILED [class=1, true class=2] features=(7.10,3.00,5.90,2.10) Iris_PerceptronClassifier (EURUSD,H1) model:PerceptronClassifier FAILED [class=1, true class=2] features=(6.30,2.90,5.60,1.80) Iris_PerceptronClassifier (EURUSD,H1) model=PerceptronClassifier batch test accuracy=0.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %61.33'tür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.16.3. Perceptron Classifier modelinin ONNX gösterimi
Şekil 30. Netron'da Perceptron Classifier modelinin ONNX gösterimi
2.17. Stochastic Gradient Descent Classifier
SGD Classifier (Stochastic Gradient Descent Classifier), sınıflandırma görevleri için kullanılan bir makine öğrenimi yöntemidir. Doğrusal modellerin özel bir durumudur ve stokastik gradyan iniş kullanılarak eğitilen doğrusal bir sınıflandırıcıdır.
SGD Classifier’ın prensipleri:
- Doğrusal hiperdüzlem: SGD Classifier, çok boyutlu özellik uzayında iki sınıfı ayıran doğrusal bir hiperdüzlem oluşturur. Bu hiperdüzlem, modelin ağırlıkları (katsayıları) tarafından belirlenir.
- Stokastik gradyan iniş: Yöntem stokastik gradyan iniş kullanılarak eğitilir; bu da ağırlık güncellemelerinin tüm veri kümesi yerine eğitim veri kümesindeki (veya rastgele seçilen bir alt kümedeki) her nesne üzerinde gerçekleştirildiği anlamına gelir. Bu, SGD Classifier’ı büyük hacimli veriler ve çevrimiçi öğrenme için uygun hale getirir.
- Kayıp fonksiyonu: SGD Classifier, ikili sınıflandırma için lojistik kayıp fonksiyonu veya çok sınıflı sınıflandırma için softmax kayıp fonksiyonu gibi bir kayıp fonksiyonunu optimize eder.
SGD Classifier’ın avantajları:
- Eğitim hızı: SGD Classifier, stokastik gradyan iniş sayesinde özellikle büyük hacimli veriler üzerinde hızlı bir şekilde eğitilir.
- Çevrimiçi öğrenme için uygundur: Bu yöntem, verilerin akış halinde geldiği ve yeni veriler geldikçe modelin güncellenmesi gereken çevrimiçi öğrenme görevleri için çok uygundur.
SGD Classifier’ın sınırlamaları:
- Parametrelere duyarlılık: SGD Classifier, öğrenme oranı ve düzenlileştirme parametresi gibi dikkatli ayarlama gerektiren birçok hiperparametreye sahiptir.
- Ağırlık başlatma: Ağırlıkların ilk seçimi yakınsamayı ve model kalitesini etkileyebilir.
- Yerel minimumlara yakınsama: SGD yönteminin stokastik yapısı nedeniyle, kayıp fonksiyonunun yerel minimumlarına yakınsayabilir ve bu da model kalitesini etkileyebilir.
SGD Classifier, özellikle hızlı işleme gerektiren büyük hacimli verilerle uğraşırken ikili ve çok sınıflı sınıflandırma görevleri için kullanılabilen çok yönlü bir makine öğrenimi yöntemidir. Yüksek sınıflandırma doğruluğu elde etmek için hiperparametrelerini uygun şekilde ayarlamak ve yakınsamayı izlemek önemlidir.
2.17.1. Stochastic Gradient Descent Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir SGD Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_SGDClassifier.py # The code demonstrates the process of training Stochastic Gradient Descent Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.linear_model import SGDClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 an SGD Classifier model sgd_model = SGDClassifier(max_iter=1000, random_state=42) # train the model on the entire dataset sgd_model.fit(X, y) # predict classes for the entire dataset y_pred = sgd_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of SGD Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(sgd_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "sgd_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of SGD Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 0.96 1.00 0.98 50
Python 1 0.88 0.92 0.90 50
Python 2 0.96 0.88 0.92 50
Python
Python accuracy 0.93 150
Python macro avg 0.93 0.93 0.93 150
Python weighted avg 0.93 0.93 0.93 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\perceptron_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of SGD Classifier model in ONNX format: 0.9333333333333333
2.17.2. Stochastic Gradient Descent Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_SGDClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "sgd_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="SGDClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=65 FAILED [class=0, true class=1] features=(5.60,2.90,3.60,1.30] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=86 FAILED [class=0, true class=1] features=(6.00,3.40,4.50,1.60] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=124 FAILED [class=1, true class=2] features=(6.30,2.70,4.90,1.80] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=127 FAILED [class=1, true class=2] features=(6.20,2.80,4.80,1.80] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier correct results: 93.33% Iris_SGDClassifier (EURUSD,H1) model=SGDClassifier all samples accuracy=0.933333 Iris_SGDClassifier (EURUSD,H1) model:SGDClassifier FAILED [class=1, true class=2] features=(6.30,2.70,4.90,1.80) Iris_SGDClassifier (EURUSD,H1) model=SGDClassifier batch test accuracy=0.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %93.33'tür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.17.3. Stochastic Gradient Descent Classifier modelinin ONNX gösterimi
Şekil 31. Netron'da Stochastic Gradient Descent Classifier modelinin ONNX gösterimi
2.18. Gaussian Naive Bayes (GNB) Classifier
Gaussian Naive Bayes (GNB) Classifier, sınıflandırma görevleri için kullanılan Bayes olasılık modeline dayalı bir makine öğrenimi yöntemidir. Saf Bayes sınıflandırıcıları ailesinin bir parçasıdır ve tüm özelliklerin bağımsız olduğunu ve normal bir dağılıma sahip olduğunu varsayar.
Gaussian Naive Bayes Classifier’ın prensipleri:
- Bayes yaklaşımı: GNB, bir nesnenin her bir sınıfa ait olma olasılığını hesaplamak için Bayes teoremini kullanan Bayes sınıflandırma yaklaşımına dayanmaktadır.
- Saf yaklaşım: GNB'deki temel varsayım, tüm özelliklerin bağımsız olduğu ve normal (Gauss) bir dağılım izlediğidir. Bu varsayım saf olarak kabul edilir çünkü gerçek dünya verilerinde özellikler genellikle birbirleriyle ilişkilidir.
- Parametre hesaplaması: GNB modeli, her bir sınıftaki her bir özellik için dağılımın parametrelerini (ortalama ve standart sapma) hesaplayarak eğitim veri kümesi üzerinde eğitilir.
Gaussian Naive Bayes Classifier’ın avantajları:
- Basitlik ve eğitim hızı: GNB çok basit bir algoritmadır ve büyük veri kümelerinde bile hızlı bir şekilde eğitilir.
- Küçük ve orta ölçekli veriler için etkililik: GNB, özellikle normal özellik dağılımları varsayımı geçerli olduğunda, az veya orta sayıda özelliğe sahip sınıflandırma görevleri için etkili olabilir.
Gaussian Naive Bayes Classifier’ın sınırlamaları:
- Saf yaklaşım: Özellik bağımsızlığı ve normal dağılım varsayımı, gerçek dünya verileri için aşırı basit ve yanlış olabilir, bu da sınıflandırma doğruluğunun azalmasına neden olur.
- Aykırı değerlere hassasiyet: GNB, normal dağılımın parametrelerini önemli ölçüde çarpıtabileceğinden verilerdeki aykırı değerlere karşı hassas olabilir.
- Özellik bağımlılıklarının yakalanamaması: Bağımsızlık varsayımı nedeniyle, GNB özellikler arasındaki bağımlılıkları hesaba katmaz.
Gaussian Naive Bayes Classifier, özellikle normal özellik dağılımları varsayımı yaklaşık olarak karşılandığında, basit sınıflandırma görevleri için iyi bir seçimdir. Bununla birlikte, özelliklerin birbiriyle ilişkili olduğu veya normal bir dağılım izlemediği daha karmaşık görevlerde, destek vektör makineleri (SVM) veya gradyan artırma gibi diğer yöntemler daha doğru sonuçlar sağlayabilir.
2.18.1. Gaussian Naive Bayes (GNB) Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Gaussian Naive Bayes (GNB) Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_GaussianNaiveBayesClassifier.py # The code demonstrates the process of training Gaussian Naive Bayes Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.naive_bayes import GaussianNB from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Gaussian Naive Bayes (GNB) Classifier model gnb_model = GaussianNB() # train the model on the entire dataset gnb_model.fit(X, y) # predict classes for the entire dataset y_pred = gnb_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Gaussian Naive Bayes (GNB) Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(gnb_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "gnb_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Gaussian Naive Bayes (GNB) Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.94 0.94 0.94 50
Python 2 0.94 0.94 0.94 50
Python
Python accuracy 0.96 150
Python macro avg 0.96 0.96 0.96 150
Python weighted avg 0.96 0.96 0.96 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\gnb_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Gaussian Naive Bayes (GNB) Classifier model in ONNX format: 0.96
2.18.2. Gaussian Naive Bayes (GNB) Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_GaussianNaiveBayesClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "gnb_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="GaussianNaiveBayesClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_GaussianNaiveBayesClassifier (EURUSD,H1) model:GaussianNaiveBayesClassifier sample=53 FAILED [class=2, true class=1] features=(6.90,3.10,4.90,1.50] Iris_GaussianNaiveBayesClassifier (EURUSD,H1) model:GaussianNaiveBayesClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_GaussianNaiveBayesClassifier (EURUSD,H1) model:GaussianNaiveBayesClassifier sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_GaussianNaiveBayesClassifier (EURUSD,H1) model:GaussianNaiveBayesClassifier sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_GaussianNaiveBayesClassifier (EURUSD,H1) model:GaussianNaiveBayesClassifier sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_GaussianNaiveBayesClassifier (EURUSD,H1) model:GaussianNaiveBayesClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_GaussianNaiveBayesClassifier (EURUSD,H1) model:GaussianNaiveBayesClassifier correct results: 96.00% Iris_GaussianNaiveBayesClassifier (EURUSD,H1) model=GaussianNaiveBayesClassifier all samples accuracy=0.960000 Iris_GaussianNaiveBayesClassifier (EURUSD,H1) model=GaussianNaiveBayesClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %96'dır ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.18.3. Gaussian Naive Bayes (GNB) Classifier modelinin ONNX gösterimi
Şekil 32. Netron'da Gaussian Naive Bayes (GNB) Classifier modelinin ONNX gösterimi
2.19. Multinomial Naive Bayes (MNB) Classifier
Multinomial Naive Bayes (MNB) Classifier, Bayes olasılık modeline dayalı bir makine öğrenme yöntemidir ve özellikle metin işlemede sınıflandırma görevleri için kullanılır. Saf Bayes sınıflandırıcılarının varyantlarından biridir ve özelliklerin metindeki kelime sayısı gibi sayıları temsil ettiğini varsayar.
Multinomial Naive Bayes Classifier’ın prensipleri:
- Bayes yaklaşımı: MNB ayrıca, bir nesnenin her sınıfa ait olma olasılığını hesaplamak için Bayes teoremini kullanarak sınıflandırmaya yönelik Bayes yaklaşımını takip eder.
- Çok terimli dağılım varsayımı: MNB'deki temel varsayım, özelliklerin metindeki kelime sayısı gibi sayıları temsil ettiği ve çok terimli bir dağılım izlediğidir. Bu varsayım genellikle metinsel veriler için geçerlidir.
- Parametre hesaplaması: MNB modeli, her bir sınıftaki her bir özellik için dağılımın parametreleri hesaplanarak eğitim veri kümesi üzerinde eğitilir.
Multinomial Naive Bayes Classifier’ın avantajları:
- Metin işlemede etkililik: MNB, özellik sayıları varsayımı sayesinde metin sınıflandırması veya spam filtreleme gibi metinsel verilerin analiziyle ilgili görevlerde iyi performans gösterir.
- Basitlik ve eğitim hızı: Diğer saf Bayes sınıflandırıcıları gibi, MNB de büyük hacimli metin verilerinde bile hızlı bir şekilde eğitilen basit bir algoritmadır.
Multinomial Naive Bayes Classifier’ın sınırlamaları:
- Saf yaklaşım: Özelliklerin çok terimli dağılımı varsayımı, özellikle özellikler karmaşık yapılara sahip olduğunda, gerçek dünya verileri için aşırı basit ve yanlış olabilir.
- Kelime sıralamasını hesaba katamama: MNB, belirli metin analizi görevlerinde önemli olabilen metindeki kelimelerin sırasını dikkate almaz.
- Nadir kelimelere duyarlılık: MNB nadir kelimelere karşı hassas olabilir ve yetersiz sayıda olması sınıflandırma doğruluğunu azaltabilir.
Multinomial Naive Bayes Classifier, özellikle özellikler metindeki kelime sayısı gibi sayılarla ilgili olduğunda, metin analizi görevleri için kullanışlı bir yöntemdir. Metin sınıflandırma, belge kategorizasyonu ve diğer metin analizleri için doğal dil işlemede (NLP) yaygın olarak kullanılmaktadır.
2.19.1. Multinomial Naive Bayes (MNB) Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Multinomial Naive Bayes (MNB) Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_MultinomialNaiveBayesClassifier.py # The code demonstrates the process of training Multinomial Naive Bayes (MNB) Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.naive_bayes import MultinomialNB from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Multinomial Naive Bayes (MNB) Classifier model mnb_model = MultinomialNB() # train the model on the entire dataset mnb_model.fit(X, y) # predict classes for the entire dataset y_pred = mnb_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Multinomial Naive Bayes (MNB) Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(mnb_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "mnb_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Multinomial Naive Bayes (MNB) Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.94 0.92 0.93 50
Python 2 0.92 0.94 0.93 50
Python
Python accuracy 0.95 150
Python macro avg 0.95 0.95 0.95 150
Python weighted avg 0.95 0.95 0.95 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\mnb_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Multinomial Naive Bayes (MNB) Classifier model in ONNX format: 0.9533333333333334
2.19.2. Multinomial Naive Bayes (MNB) Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_MultinomialNaiveBayesClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "mnb_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="MultinomialNaiveBayesClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model:MultinomialNaiveBayesClassifier sample=69 FAILED [class=2, true class=1] features=(6.20,2.20,4.50,1.50] Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model:MultinomialNaiveBayesClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model:MultinomialNaiveBayesClassifier sample=73 FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50] Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model:MultinomialNaiveBayesClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model:MultinomialNaiveBayesClassifier sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model:MultinomialNaiveBayesClassifier sample=132 FAILED [class=1, true class=2] features=(7.90,3.80,6.40,2.00] Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model:MultinomialNaiveBayesClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model:MultinomialNaiveBayesClassifier correct results: 95.33% Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model=MultinomialNaiveBayesClassifier all samples accuracy=0.953333 Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model:MultinomialNaiveBayesClassifier FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50) Iris_MultinomialNaiveBayesClassifier (EURUSD,H1) model=MultinomialNaiveBayesClassifier batch test accuracy=0.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %95.33'tür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.19.3. Multinomial Naive Bayes (MNB) Classifier modelinin ONNX gösterimi
Şekil 33. Netron'da Multinomial Naive Bayes (MNB) Classifier modelinin ONNX gösterimi
2.20. Complement Naive Bayes (CNB) Classifier
Complement Naive Bayes (CNB) Classifier, bir sınıfın diğerinden önemli ölçüde daha yaygın olabileceği dengesiz verilerle çalışmak üzere özel olarak tasarlanmış bir saf Bayes sınıflandırıcı çeşididir. Bu sınıflandırıcı, sınıf dengesizliğini ele almak için klasik saf Bayes yöntemini uyarlar.
Complement Naive Bayes Classifier’ın prensipleri:
- Bayes yaklaşımı: Diğer Bayes sınıflandırıcıları gibi CNB de sınıflandırmada Bayes yaklaşımını izler ve bir nesnenin her bir sınıfa ait olma olasılığını hesaplamak için Bayes teoremini kullanır.
- Sınıf dengesizliğinin çözülmesi: CNB'nin birincil amacı sınıf dengesizliğini düzeltmektir. CNB, standart saf Bayes yönteminin yaptığı gibi sınıftaki özelliklerin olasılığını dikkate almak yerine, sınıf dışındaki özelliklerin olasılığını dikkate almaya çalışır. Bu, özellikle bir sınıfın diğerine göre önemli ölçüde daha az temsil edildiği durumlarda faydalıdır.
- Parametre hesaplaması: CNB modeli, sınıf dışındaki her özellik için dağılımın parametreleri hesaplanarak eğitim veri kümesi üzerinde eğitilir.
Complement Naive Bayes Classifier’ın avantajları:
- Dengesiz veriler için uygunluk: CNB, sınıfların farklı sıklığa sahip olduğu dengesiz verilerle sınıflandırma görevlerinde iyi performans gösterir.
- Basitlik ve eğitim hızı: Diğer saf Bayes sınıflandırıcıları gibi CNB de büyük hacimli veriler üzerinde bile hızlı bir şekilde eğitilen basit bir algoritmadır.
Complement Naive Bayes Classifier’ın sınırlamaları:
- Düzenlileştirme parametresi seçimine duyarlılık: Diğer Bayes yöntemlerinde olduğu gibi, düzenlileştirme parametresi için doğru değerin seçilmesi ayarlama ve değerlendirme gerektirebilir.
- Saf yaklaşım: Diğer saf Bayes sınıflandırıcıları gibi CNB de özellik bağımsızlığı varsayımını yapar ve bu varsayım bazı görevler için aşırı basit olabilir.
Complement Naive Bayes Classifier, özellikle bir sınıfın diğerinden önemli ölçüde daha az temsil edildiği durumlarda, dengesiz verilere sahip sınıflandırma görevleri için iyi bir seçimdir. Görüş analizi veya spam filtreleme gibi kelimelerin sınıflar arasında büyük ölçüde dengesiz olabileceği metin sınıflandırma görevlerinde özellikle yararlı olabilir.
2.20.1. Complement Naive Bayes (CNB) Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Complement Naive Bayes (CNB) Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_CNBClassifier.py # The code demonstrates the process of training Complement Naive Bayes (CNB) Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.naive_bayes import ComplementNB from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Complement Naive Bayes (CNB) Classifier model cnb_model = ComplementNB() # train the model on the entire dataset cnb_model.fit(X, y) # predict classes for the entire dataset y_pred = cnb_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Complement Naive Bayes (CNB) Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(cnb_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "cnb_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Complement Naive Bayes (CNB) Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 0.96 1.00 0.98 50
Python 1 0.00 0.00 0.00 50
Python 2 0.51 1.00 0.68 50
Python
Python accuracy 0.67 150
Python macro avg 0.49 0.67 0.55 150
Python weighted avg 0.49 0.67 0.55 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\cnb_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Complement Naive Bayes (CNB) Classifier model in ONNX format: 0.6666666666666666
2.20.2. Complement Naive Bayes (CNB) Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_CNBClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "cnb_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="CNBClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=51 FAILED [class=2, true class=1] features=(7.00,3.20,4.70,1.40] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=52 FAILED [class=2, true class=1] features=(6.40,3.20,4.50,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=53 FAILED [class=2, true class=1] features=(6.90,3.10,4.90,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=54 FAILED [class=2, true class=1] features=(5.50,2.30,4.00,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=55 FAILED [class=2, true class=1] features=(6.50,2.80,4.60,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=56 FAILED [class=2, true class=1] features=(5.70,2.80,4.50,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=57 FAILED [class=2, true class=1] features=(6.30,3.30,4.70,1.60] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=58 FAILED [class=2, true class=1] features=(4.90,2.40,3.30,1.00] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=59 FAILED [class=2, true class=1] features=(6.60,2.90,4.60,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=60 FAILED [class=2, true class=1] features=(5.20,2.70,3.90,1.40] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=61 FAILED [class=2, true class=1] features=(5.00,2.00,3.50,1.00] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=62 FAILED [class=2, true class=1] features=(5.90,3.00,4.20,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=63 FAILED [class=2, true class=1] features=(6.00,2.20,4.00,1.00] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=64 FAILED [class=2, true class=1] features=(6.10,2.90,4.70,1.40] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=65 FAILED [class=2, true class=1] features=(5.60,2.90,3.60,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=66 FAILED [class=2, true class=1] features=(6.70,3.10,4.40,1.40] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=67 FAILED [class=2, true class=1] features=(5.60,3.00,4.50,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=68 FAILED [class=2, true class=1] features=(5.80,2.70,4.10,1.00] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=69 FAILED [class=2, true class=1] features=(6.20,2.20,4.50,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=70 FAILED [class=2, true class=1] features=(5.60,2.50,3.90,1.10] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=72 FAILED [class=2, true class=1] features=(6.10,2.80,4.00,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=73 FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=74 FAILED [class=2, true class=1] features=(6.10,2.80,4.70,1.20] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=75 FAILED [class=2, true class=1] features=(6.40,2.90,4.30,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=76 FAILED [class=2, true class=1] features=(6.60,3.00,4.40,1.40] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=77 FAILED [class=2, true class=1] features=(6.80,2.80,4.80,1.40] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=79 FAILED [class=2, true class=1] features=(6.00,2.90,4.50,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=80 FAILED [class=0, true class=1] features=(5.70,2.60,3.50,1.00] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=81 FAILED [class=2, true class=1] features=(5.50,2.40,3.80,1.10] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=82 FAILED [class=2, true class=1] features=(5.50,2.40,3.70,1.00] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=83 FAILED [class=2, true class=1] features=(5.80,2.70,3.90,1.20] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=86 FAILED [class=2, true class=1] features=(6.00,3.40,4.50,1.60] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=87 FAILED [class=2, true class=1] features=(6.70,3.10,4.70,1.50] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=88 FAILED [class=2, true class=1] features=(6.30,2.30,4.40,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=89 FAILED [class=2, true class=1] features=(5.60,3.00,4.10,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=90 FAILED [class=2, true class=1] features=(5.50,2.50,4.00,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=91 FAILED [class=2, true class=1] features=(5.50,2.60,4.40,1.20] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=92 FAILED [class=2, true class=1] features=(6.10,3.00,4.60,1.40] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=93 FAILED [class=2, true class=1] features=(5.80,2.60,4.00,1.20] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=94 FAILED [class=2, true class=1] features=(5.00,2.30,3.30,1.00] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=95 FAILED [class=2, true class=1] features=(5.60,2.70,4.20,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=96 FAILED [class=2, true class=1] features=(5.70,3.00,4.20,1.20] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=97 FAILED [class=2, true class=1] features=(5.70,2.90,4.20,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=98 FAILED [class=2, true class=1] features=(6.20,2.90,4.30,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=99 FAILED [class=0, true class=1] features=(5.10,2.50,3.00,1.10] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier sample=100 FAILED [class=2, true class=1] features=(5.70,2.80,4.10,1.30] Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier correct results: 66.67% Iris_CNBClassifier (EURUSD,H1) model=CNBClassifier all samples accuracy=0.666667 Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50) Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier FAILED [class=2, true class=1] features=(7.00,3.20,4.70,1.40) Iris_CNBClassifier (EURUSD,H1) model:CNBClassifier FAILED [class=2, true class=1] features=(6.40,3.20,4.50,1.50) Iris_CNBClassifier (EURUSD,H1) model=CNBClassifier batch test accuracy=0.000000Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %66.67'dir ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.20.3. Complement Naive Bayes (CNB) Classifier modelinin ONNX gösterimi
Şekil 34. Netron'da Complement Naive Bayes (CNB) Classifier modelinin ONNX gösterimi
2.21. Bernoulli Naive Bayes (BNB) Classifier
Bernoulli Naive Bayes (BNB) Classifier, ikili sınıflandırma görevleri için kullanılan başka bir saf Bayes sınıflandırıcı çeşididir. Bu sınıflandırıcı, özelliklerin ikili veri olarak temsil edildiği durumlarda, örneğin özelliklerin metindeki kelimelerin varlığı veya yokluğu olabileceği metin analizinde özellikle kullanışlıdır.
Bernoulli Naive Bayes Classifier’ın prensipleri:
- Bayes yaklaşımı: Diğer Bayes sınıflandırıcıları gibi BNB de sınıflandırmada Bayes yaklaşımını izler ve bir nesnenin her bir sınıfa ait olma olasılığını hesaplamak için Bayes teoremini kullanır.
- İkili özellikler varsayımı: BNB'nin birincil varsayımı, özelliklerin ikili veri olarak temsil edilmesidir, yani 1 ve 0 gibi yalnızca iki değere sahip olabilirler; burada 1 özelliğin varlığını, 0 ise yokluğunu temsil eder.
- Parametre hesaplaması: BNB modeli, her sınıftaki her özellik için dağılımın parametreleri hesaplanarak eğitim veri kümesi üzerinde eğitilir.
Bernoulli Naive Bayes Classifier’ın avantajları:
- İkili veriler için etkililik: BNB, özelliklerin ikili veri olarak temsil edildiği görevlerde iyi çalışır ve özellikle metin analizi veya olay sınıflandırmasında yararlı olabilir.
- Basitlik ve eğitim hızı: Diğer saf Bayes sınıflandırıcıları gibi BNB de hızlı bir şekilde eğitilen basit bir algoritmadır.
Bernoulli Naive Bayes Classifier’ın sınırlamaları:
- İkili özellikler kısıtı: BNB, özelliklerin ikili olmadığı görevler için uygun değildir. Özelliklerin ikiden fazla değeri varsa, BNB bu bilgiyi dikkate almaz.
- Saf yaklaşım: Diğer saf Bayes sınıflandırıcıları gibi, BNB de özellik bağımsızlığı varsayımını yapar ve bu varsayım bazı görevler için aşırı basit olabilir.
Bernoulli Naive Bayes Classifier, metnin görüş analizi veya spam sınıflandırması gibi ikili özelliklere sahip ikili sınıflandırma görevleri için iyi bir seçimdir. Kullanımı kolaydır ve bu tür verilerle iyi performans gösterir.
2.21.1. Bernoulli Naive Bayes (BNB) Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Bernoulli Naive Bayes (BNB) Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_BNBClassifier.py # The code demonstrates the process of training Bernoulli Naive Bayes (BNB) Classifier on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.naive_bayes import BernoulliNB from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Bernoulli Naive Bayes (BNB) Classifier model bnb_model = BernoulliNB() # train the model on the entire dataset bnb_model.fit(X, y) # predict classes for the entire dataset y_pred = bnb_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Bernoulli Naive Bayes (BNB) Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(bnb_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "bnb_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Bernoulli Naive Bayes (BNB) Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 0.33 1.00 0.50 50
Python 1 0.00 0.00 0.00 50
Python 2 0.00 0.00 0.00 50
Python
Python accuracy 0.33 150
Python macro avg 0.11 0.33 0.17 150
Python weighted avg 0.11 0.33 0.17 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\bnb_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Bernoulli Naive Bayes (BNB) Classifier model in ONNX format: 0.3333333333333333
2.21.2. Bernoulli Naive Bayes (BNB) Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_BNBClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "bnb_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="BNBClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=51 FAILED [class=0, true class=1] features=(7.00,3.20,4.70,1.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=52 FAILED [class=0, true class=1] features=(6.40,3.20,4.50,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=53 FAILED [class=0, true class=1] features=(6.90,3.10,4.90,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=54 FAILED [class=0, true class=1] features=(5.50,2.30,4.00,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=55 FAILED [class=0, true class=1] features=(6.50,2.80,4.60,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=56 FAILED [class=0, true class=1] features=(5.70,2.80,4.50,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=57 FAILED [class=0, true class=1] features=(6.30,3.30,4.70,1.60] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=58 FAILED [class=0, true class=1] features=(4.90,2.40,3.30,1.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=59 FAILED [class=0, true class=1] features=(6.60,2.90,4.60,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=60 FAILED [class=0, true class=1] features=(5.20,2.70,3.90,1.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=61 FAILED [class=0, true class=1] features=(5.00,2.00,3.50,1.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=62 FAILED [class=0, true class=1] features=(5.90,3.00,4.20,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=63 FAILED [class=0, true class=1] features=(6.00,2.20,4.00,1.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=64 FAILED [class=0, true class=1] features=(6.10,2.90,4.70,1.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=65 FAILED [class=0, true class=1] features=(5.60,2.90,3.60,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=66 FAILED [class=0, true class=1] features=(6.70,3.10,4.40,1.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=67 FAILED [class=0, true class=1] features=(5.60,3.00,4.50,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=68 FAILED [class=0, true class=1] features=(5.80,2.70,4.10,1.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=69 FAILED [class=0, true class=1] features=(6.20,2.20,4.50,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=70 FAILED [class=0, true class=1] features=(5.60,2.50,3.90,1.10] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=71 FAILED [class=0, true class=1] features=(5.90,3.20,4.80,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=72 FAILED [class=0, true class=1] features=(6.10,2.80,4.00,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=73 FAILED [class=0, true class=1] features=(6.30,2.50,4.90,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=74 FAILED [class=0, true class=1] features=(6.10,2.80,4.70,1.20] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=75 FAILED [class=0, true class=1] features=(6.40,2.90,4.30,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=76 FAILED [class=0, true class=1] features=(6.60,3.00,4.40,1.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=77 FAILED [class=0, true class=1] features=(6.80,2.80,4.80,1.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=78 FAILED [class=0, true class=1] features=(6.70,3.00,5.00,1.70] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=79 FAILED [class=0, true class=1] features=(6.00,2.90,4.50,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=80 FAILED [class=0, true class=1] features=(5.70,2.60,3.50,1.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=81 FAILED [class=0, true class=1] features=(5.50,2.40,3.80,1.10] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=82 FAILED [class=0, true class=1] features=(5.50,2.40,3.70,1.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=83 FAILED [class=0, true class=1] features=(5.80,2.70,3.90,1.20] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=84 FAILED [class=0, true class=1] features=(6.00,2.70,5.10,1.60] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=85 FAILED [class=0, true class=1] features=(5.40,3.00,4.50,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=86 FAILED [class=0, true class=1] features=(6.00,3.40,4.50,1.60] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=87 FAILED [class=0, true class=1] features=(6.70,3.10,4.70,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=88 FAILED [class=0, true class=1] features=(6.30,2.30,4.40,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=89 FAILED [class=0, true class=1] features=(5.60,3.00,4.10,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=90 FAILED [class=0, true class=1] features=(5.50,2.50,4.00,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=91 FAILED [class=0, true class=1] features=(5.50,2.60,4.40,1.20] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=92 FAILED [class=0, true class=1] features=(6.10,3.00,4.60,1.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=93 FAILED [class=0, true class=1] features=(5.80,2.60,4.00,1.20] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=94 FAILED [class=0, true class=1] features=(5.00,2.30,3.30,1.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=95 FAILED [class=0, true class=1] features=(5.60,2.70,4.20,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=96 FAILED [class=0, true class=1] features=(5.70,3.00,4.20,1.20] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=97 FAILED [class=0, true class=1] features=(5.70,2.90,4.20,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=98 FAILED [class=0, true class=1] features=(6.20,2.90,4.30,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=99 FAILED [class=0, true class=1] features=(5.10,2.50,3.00,1.10] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=100 FAILED [class=0, true class=1] features=(5.70,2.80,4.10,1.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=101 FAILED [class=0, true class=2] features=(6.30,3.30,6.00,2.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=102 FAILED [class=0, true class=2] features=(5.80,2.70,5.10,1.90] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=103 FAILED [class=0, true class=2] features=(7.10,3.00,5.90,2.10] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=104 FAILED [class=0, true class=2] features=(6.30,2.90,5.60,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=105 FAILED [class=0, true class=2] features=(6.50,3.00,5.80,2.20] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=106 FAILED [class=0, true class=2] features=(7.60,3.00,6.60,2.10] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=107 FAILED [class=0, true class=2] features=(4.90,2.50,4.50,1.70] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=108 FAILED [class=0, true class=2] features=(7.30,2.90,6.30,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=109 FAILED [class=0, true class=2] features=(6.70,2.50,5.80,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=110 FAILED [class=0, true class=2] features=(7.20,3.60,6.10,2.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=111 FAILED [class=0, true class=2] features=(6.50,3.20,5.10,2.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=112 FAILED [class=0, true class=2] features=(6.40,2.70,5.30,1.90] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=113 FAILED [class=0, true class=2] features=(6.80,3.00,5.50,2.10] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=114 FAILED [class=0, true class=2] features=(5.70,2.50,5.00,2.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=115 FAILED [class=0, true class=2] features=(5.80,2.80,5.10,2.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=116 FAILED [class=0, true class=2] features=(6.40,3.20,5.30,2.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=117 FAILED [class=0, true class=2] features=(6.50,3.00,5.50,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=118 FAILED [class=0, true class=2] features=(7.70,3.80,6.70,2.20] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=119 FAILED [class=0, true class=2] features=(7.70,2.60,6.90,2.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=120 FAILED [class=0, true class=2] features=(6.00,2.20,5.00,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=121 FAILED [class=0, true class=2] features=(6.90,3.20,5.70,2.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=122 FAILED [class=0, true class=2] features=(5.60,2.80,4.90,2.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=123 FAILED [class=0, true class=2] features=(7.70,2.80,6.70,2.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=124 FAILED [class=0, true class=2] features=(6.30,2.70,4.90,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=125 FAILED [class=0, true class=2] features=(6.70,3.30,5.70,2.10] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=126 FAILED [class=0, true class=2] features=(7.20,3.20,6.00,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=127 FAILED [class=0, true class=2] features=(6.20,2.80,4.80,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=128 FAILED [class=0, true class=2] features=(6.10,3.00,4.90,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=129 FAILED [class=0, true class=2] features=(6.40,2.80,5.60,2.10] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=130 FAILED [class=0, true class=2] features=(7.20,3.00,5.80,1.60] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=131 FAILED [class=0, true class=2] features=(7.40,2.80,6.10,1.90] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=132 FAILED [class=0, true class=2] features=(7.90,3.80,6.40,2.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=133 FAILED [class=0, true class=2] features=(6.40,2.80,5.60,2.20] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=134 FAILED [class=0, true class=2] features=(6.30,2.80,5.10,1.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=135 FAILED [class=0, true class=2] features=(6.10,2.60,5.60,1.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=136 FAILED [class=0, true class=2] features=(7.70,3.00,6.10,2.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=137 FAILED [class=0, true class=2] features=(6.30,3.40,5.60,2.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=138 FAILED [class=0, true class=2] features=(6.40,3.10,5.50,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=139 FAILED [class=0, true class=2] features=(6.00,3.00,4.80,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=140 FAILED [class=0, true class=2] features=(6.90,3.10,5.40,2.10] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=141 FAILED [class=0, true class=2] features=(6.70,3.10,5.60,2.40] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=142 FAILED [class=0, true class=2] features=(6.90,3.10,5.10,2.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=143 FAILED [class=0, true class=2] features=(5.80,2.70,5.10,1.90] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=144 FAILED [class=0, true class=2] features=(6.80,3.20,5.90,2.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=145 FAILED [class=0, true class=2] features=(6.70,3.30,5.70,2.50] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=146 FAILED [class=0, true class=2] features=(6.70,3.00,5.20,2.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=147 FAILED [class=0, true class=2] features=(6.30,2.50,5.00,1.90] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=148 FAILED [class=0, true class=2] features=(6.50,3.00,5.20,2.00] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=149 FAILED [class=0, true class=2] features=(6.20,3.40,5.40,2.30] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier sample=150 FAILED [class=0, true class=2] features=(5.90,3.00,5.10,1.80] Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier correct results: 33.33% Iris_BNBClassifier (EURUSD,H1) model=BNBClassifier all samples accuracy=0.333333 Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier FAILED [class=0, true class=1] features=(6.30,2.50,4.90,1.50) Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier FAILED [class=0, true class=2] features=(6.30,2.70,4.90,1.80) Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier FAILED [class=0, true class=1] features=(7.00,3.20,4.70,1.40) Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier FAILED [class=0, true class=1] features=(6.40,3.20,4.50,1.50) Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier FAILED [class=0, true class=2] features=(6.30,3.30,6.00,2.50) Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier FAILED [class=0, true class=2] features=(5.80,2.70,5.10,1.90) Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier FAILED [class=0, true class=2] features=(7.10,3.00,5.90,2.10) Iris_BNBClassifier (EURUSD,H1) model:BNBClassifier FAILED [class=0, true class=2] features=(6.30,2.90,5.60,1.80) Iris_BNBClassifier (EURUSD,H1) model=BNBClassifier batch test accuracy=0.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %33.33'tür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.21.3. Bernoulli Naive Bayes (BNB) Classifier modelinin ONNX gösterimi
Şekil 35. Netron'da Bernoulli Naive Bayes (BNB) Classifier modelinin ONNX gösterimi
2.22. Multilayer Perceptron Classifier
Multilayer Perceptron (MLP) Classifier, sınıflandırma görevleri için kullanılan çok katmanlı bir sinir ağıdır. Bir girdi katmanı, gizli katmanlar ve bir çıktı katmanı dahil olmak üzere birden fazla nöron katmanından oluşur. MLP Classifier, verilerdeki karmaşık doğrusal olmayan bağımlılıkları öğrenme yeteneğine sahiptir.
MLP Classifier’ın prensipleri:
- Çok katmanlı mimari: MLP Classifier, bir girdi katmanı, bir veya daha fazla gizli katman ve bir çıktı katmanı içeren çok katmanlı bir mimariye sahiptir. Katmanlardaki her nöron, öğrenilen ağırlıklarla komşu katmanlardaki nöronlara bağlanır.
- Aktivasyon fonksiyonları: Her nöronun içinde, modele doğrusal olmayan bir özellik katan ve MLP Classifier’ın karmaşık veri bağımlılıklarını modellemesine olanak tanıyan bir aktivasyon fonksiyonu uygulanır.
- Geri yayılım ile eğitim: MLP Classifier, modelin tahminleri ile gerçek sınıf etiketleri arasındaki hatayı en aza indiren geri yayılım yöntemi kullanılarak eğitilir.
MLP Classifier’ın avantajları:
- Karmaşık bağımlılıkları modelleme becerisi: MLP Classifier, verilerdeki karmaşık doğrusal olmayan bağımlılıkları öğrenebilir ve sonuç olarak basit doğrusal modellerin yetersiz kaldığı görevlerde iyi performans gösterebilir.
- Çok yönlülük: MLP Classifier, çok sınıflı sınıflandırma ve çoklu görev problemleri de dahil olmak üzere çok çeşitli sınıflandırma görevleri için kullanılabilir.
MLP Classifier’ın sınırlamaları:
- Hiperparametrelere duyarlılık: MLP Classifier, gizli katman sayısı, her katmandaki nöron sayısı, öğrenme oranı vb. gibi birçok hiperparametreye sahiptir. Bu parametrelerin ayarlanması zaman alıcı ve kaynak yoğun olabilir.
- Büyük miktarda veri gereksinimi: MLP Classifier, özellikle modelin çok sayıda parametresi olduğunda, aşırı uyumdan kaçınmak için önemli miktarda eğitim verisi gerektirir.
- Aşırı uyum: Model çok fazla parametreye veya yetersiz veriye sahipse, aşırı uyum sağlayabilir ve yeni veriler üzerinde kötü performans gösterebilir.
MLP Classifier, özellikle veriler karmaşık bağımlılıklar sergilediğinde sınıflandırma görevleri için güçlü bir araçtır. Çeşitli sınıflandırma problemlerini çözmek için makine öğrenimi ve derin öğrenme alanlarında yaygın olarak kullanılmaktadır. Bununla birlikte, hiperparametrelerin uygun şekilde ayarlanması ve yeterli miktarda eğitim verisinin sağlanması, bu modelin başarılı bir şekilde uygulanması için gereklidir.
2.22.1. Multilayer Perceptron Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Multilayer Perceptron Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_MLPClassifier.py # The code demonstrates the process of training Multilayer Perceptron Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.neural_network import MLPClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Multilayer Perceptron (MLP) Classifier model mlp_model = MLPClassifier(max_iter=1000, random_state=42) # train the model on the entire dataset mlp_model.fit(X, y) # predict classes for the entire dataset y_pred = mlp_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Multilayer Perceptron (MLP) Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(mlp_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path +"mlp_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Multilayer Perceptron (MLP) Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 0.94 0.97 50
Python 2 0.94 1.00 0.97 50
Python
Python accuracy 0.98 150
Python macro avg 0.98 0.98 0.98 150
Python weighted avg 0.98 0.98 0.98 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\mlp_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Multilayer Perceptron (MLP) Classifier model in ONNX format: 0.98
2.22.2. Multilayer Perceptron Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_MLPClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "mlp_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="MLPClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_MLPClassifier (EURUSD,H1) model:MLPClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_MLPClassifier (EURUSD,H1) model:MLPClassifier sample=73 FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50] Iris_MLPClassifier (EURUSD,H1) model:MLPClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_MLPClassifier (EURUSD,H1) model:MLPClassifier correct results: 98.00% Iris_MLPClassifier (EURUSD,H1) model=MLPClassifier all samples accuracy=0.980000 Iris_MLPClassifier (EURUSD,H1) model:MLPClassifier FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50) Iris_MLPClassifier (EURUSD,H1) model=MLPClassifier batch test accuracy=0.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %98'dir ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.22.3. Multilayer Perceptron Classifier modelinin ONNX gösterimi
Şekil 36. Netron'da Multilayer Perceptron Classifier modelinin ONNX gösterimi
2.23. Linear Discriminant Analysis (LDA) Classifier
Linear Discriminant Analysis (LDA) Classifier, sınıflandırma görevleri için kullanılan bir makine öğrenimi yöntemidir. Boyut azaltma yöntemleri ve düşük boyutlu uzayda sınıflandırma ailesine aittir. LDA, sınıflar arasındaki ayrımı en üst düzeye çıkarmak için hiperdüzlemler oluşturur.
LDA Classifier’ın prensipleri:
- Boyut azaltma: LDA'nın ana fikri boyutun azaltılmasıdır. Veri sınıflarının maksimum düzeyde ayrıldığı yeni bir özellik uzayı bulmayı amaçlar.
- Ayrımı en üst düzeye çıkarma: LDA, farklı sınıflardaki özelliklerin ortalama değerleri arasındaki farkı maksimize eden ve her bir sınıf içindeki varyansı minimize eden hiperdüzlemler (özelliklerin doğrusal kombinasyonları) oluşturur.
- Parametre eğitimi: LDA modeli, hiperdüzlemlerin parametrelerini ve yeni özellik uzayına veri projeksiyonlarını hesaplayarak eğitim veri kümesi üzerinde eğitilir.
LDA Classifier’ın avantajları:
- İyileştirilmiş sınıf ayrımı: LDA, özellikle sınıfların orijinal özellik uzayında büyük ölçüde örtüştüğü durumlarda, verilerdeki sınıf ayrımını önemli ölçüde iyileştirebilir.
- Boyut azaltma: LDA, görselleştirme ve hesaplama karmaşıklığını azaltmak için yararlı olabilecek veri boyutunun azaltılması için de kullanılabilir.
LDA Classifier’ın sınırlamaları:
- Normallik varsayımı: LDA, özelliklerin normal bir dağılım izlediğini ve sınıfların eşit kovaryans matrislerine sahip olduğunu varsayar. Bu varsayımlar karşılanmazsa, LDA daha az doğru sonuçlar sağlayabilir.
- Aykırı değerlere hassasiyet: LDA, model parametre hesaplamalarını etkileyebileceğinden verilerdeki aykırı değerlere karşı hassas olabilir.
- Çok sınıflı sınıflandırmada zorluklar: LDA başlangıçta ikili sınıflandırma için geliştirilmiştir ve çok sınıflı görevlere genişletilmesi uyarlama gerektirir.
LDA Classifier, özellikle sınıf ayrımını iyileştirme ihtiyacı olduğunda, sınıflandırma ve boyut azaltma görevleri için değerli bir yöntemdir. İstatistik, biyoloji, tıbbi analiz vb. veri analizi ve sınıflandırması için sıklıkla kullanılır.
2.23.1. Linear Discriminant Analysis (LDA) Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Linear Discriminant Analysis (LDA) Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_LDAClassifier.py # The code demonstrates the process of training Linear Discriminant Analysis (LDA) Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.discriminant_analysis import LinearDiscriminantAnalysis from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Linear Discriminant Analysis (LDA) Classifier model lda_model = LinearDiscriminantAnalysis() # train the model on the entire dataset lda_model.fit(X, y) # predict classes for the entire dataset y_pred = lda_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Linear Discriminant Analysis (LDA) Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(lda_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path +"lda_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Linear Discriminant Analysis (LDA) Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.98 0.96 0.97 50
Python 2 0.96 0.98 0.97 50
Python
Python accuracy 0.98 150
Python macro avg 0.98 0.98 0.98 150
Python weighted avg 0.98 0.98 0.98 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\lda_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Linear Discriminant Analysis (LDA) Classifier model in ONNX format: 0.98
2.23.2. Linear Discriminant Analysis (LDA) Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_LDAClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "lda_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="LDAClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_LDAClassifier (EURUSD,H1) model:LDAClassifier sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_LDAClassifier (EURUSD,H1) model:LDAClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_LDAClassifier (EURUSD,H1) model:LDAClassifier sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_LDAClassifier (EURUSD,H1) model:LDAClassifier correct results: 98.00% Iris_LDAClassifier (EURUSD,H1) model=LDAClassifier all samples accuracy=0.980000 Iris_LDAClassifier (EURUSD,H1) model=LDAClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %98'dir ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.23.3. Linear Discriminant Analysis (LDA) Classifier modelinin ONNX gösterimi
Şekil 37. Netron'da Linear Discriminant Analysis (LDA) Classifier modelinin ONNX gösterimi
2.24. Hist Gradient Boosting
Hist Gradient Boosting Classifier, gradyan artırma ailesine ait olan ve sınıflandırma görevleri için tasarlanmış bir makine öğrenimi algoritmasıdır. Veri analizi ve makine öğreniminde yaygın olarak kullanılan verimli ve güçlü bir yöntemdir.
Hist Gradient Boosting Classifier’ın prensipleri:
- Gradyan artırma: Hist Gradient Boosting Classifier, sınıflandırmayı iyileştirmek için bir karar ağaçları topluluğu oluşturan gradyan artırma yöntemine dayanmaktadır. Bunu, zayıf modelleri sırayla eğiterek ve önceki modellerin hatalarını düzelterek yapar.
- Histogram kullanımı: Adındaki "Hist", bu algoritmanın verimli veri işleme için histogramları kullandığını ifade eder. Hist Gradient Boosting, kapsamlı özellik numaralandırması yerine özelliklerin histogramlarını oluşturarak hızlı karar ağacı oluşturmayı sağlar.
- Kalıntılar üzerine eğitim: Diğer gradyan artırma yöntemleri gibi, Hist Gradient Boosting de tahminleri iyileştirmek için her yeni ağacı bir önceki modelin kalıntıları üzerinde eğitir.
Hist Gradient Boosting Classifier’ın avantajları:
- Yüksek doğruluk: Hist Gradient Boosting Classifier, özellikle çok sayıda ağaç kullanıldığında tipik olarak yüksek sınıflandırma doğruluğu sağlar.
- Verimlilik: Histogramların kullanılması, algoritmanın büyük veri kümelerini verimli bir şekilde işlemesine ve hızlı bir şekilde bir topluluk oluşturmasına olanak tanır.
- Heterojen verileri işleme yeteneği: Algoritma, kategorik ve sayısal özellikler de dahil olmak üzere heterojen verileri işleyebilir.
Hist Gradient Boosting Classifier’ın sınırlamaları:
- Aşırı uyuma duyarlılık: Parametreler uygun şekilde ayarlanmadığında veya çok sayıda ağaç kullanıldığında, Hist Gradient Boosting Classifier aşırı uyum sağlamaya eğilimli olabilir.
- Parametre ayarlama: Diğer gradyan artırma algoritmaları gibi Hist Gradient Boosting de optimum performans için dikkatli parametre ayarı gerektirir.
Hist Gradient Boosting Classifier, veri işlemede yüksek doğruluk ve verimlilik sunan sınıflandırma ve regresyon görevleri için güçlü bir algoritmadır. Veri analizi, biyoinformatik, finans vb. gibi çeşitli alanlarda uygulamalar bulur.
2.24.1. Histogram-Based Gradient Boosting Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir Histogram-Based Gradient Boosting Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_HistGradientBoostingClassifier.py # The code demonstrates the process of training Histogram-Based Gradient Boosting Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.experimental import enable_hist_gradient_boosting from sklearn.ensemble import HistGradientBoostingClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a Histogram-Based Gradient Boosting Classifier model hist_gradient_boosting_model = HistGradientBoostingClassifier(random_state=42) # train the model on the entire dataset hist_gradient_boosting_model.fit(X, y) # predict classes for the entire dataset y_pred = hist_gradient_boosting_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of Hist Gradient Boosting Classifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(hist_gradient_boosting_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path +"hist_gradient_boosting_classifier_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of Hist Gradient Boosting Classifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 1.00 1.00 50
Python 2 1.00 1.00 1.00 50
Python
Python accuracy 1.00 150
Python macro avg 1.00 1.00 1.00 150
Python weighted avg 1.00 1.00 1.00 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\hist_gradient_boosting_classifier_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of Hist Gradient Boosting Classifier model in ONNX format: 1.0
2.24.2. Histogram-Based Gradient Boosting Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_HistGradientBoostingClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "hist_gradient_boosting_classifier_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="HistGradientBoostingClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_HistGradientBoostingClassifier (EURUSD,H1) model:HistGradientBoostingClassifier correct results: 100.00% Iris_HistGradientBoostingClassifier (EURUSD,H1) model=HistGradientBoostingClassifier all samples accuracy=1.000000 Iris_HistGradientBoostingClassifier (EURUSD,H1) model=HistGradientBoostingClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %100'dür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.24.3. Histogram-Based Gradient Boosting Classifier modelinin ONNX gösterimi
Şekil 38. Netron'da Histogram-Based Gradient Boosting Classifier modelinin ONNX gösterimi
2.25. CategoricalNB Classifier
CategoricalNB, Bayes teoremine dayanan bir sınıflandırma algoritmasıdır. Kategorik özelliklere sahip veri kümeleri için özel olarak tasarlanmıştır ve metin sınıflandırma, spam algılama ve ayrık veri içeren diğer uygulamalarda yaygın olarak kullanılmaktadır.
CategoricalNB’nin prensipleri:
- Saf Bayes sınıflandırıcı: CategoricalNB, Bayes teoremine dayanan bir saf Bayes sınıflandırıcı türüdür. Sınıf göz önüne alındığında her bir özelliğin koşullu olasılıklarını kullanarak bir dizi özellik için belirli bir sınıfa ait olma olasılığını hesaplar.
- Kategorik özellikler: Normal dağılıma sahip sürekli özellikleri varsayan Gaussian Naive Bayes Classifier’ın aksine, CategoricalNB kategorik özelliklere sahip veri kümeleri için uygundur. Her bir sınıf için her bir özelliğin olasılık dağılımını modeller.
- Bağımsızlık varsayımı: Saf Bayes sınıflandırıcıdaki "saf", özellik bağımsızlığı varsayımından gelir. CategoricalNB, sınıf göz önüne alındığında özelliklerin koşullu olarak bağımsız olduğunu varsayar. Bu varsayımın pratikte her zaman karşılanmamasına rağmen, saf Bayes yöntemleri birçok gerçek dünya veri kümesinde iyi performans gösterebilir.
CategoricalNB'nin avantajları:
- Verimlilik: CategoricalNB hesaplama açısından verimli ve büyük veri kümelerine ölçeklenebilir. Minimum bellek gerektirir ve hızlı tahminler sağlayabilir.
- Yorumlanabilirlik: Olasılıksal yapısı CategoricalNB'yi yorumlanabilir kılmaktadır. Hangi özelliklerin tahmini etkilediğine dair içgörüler sağlayabilir.
- Kategorik verilerin işlenmesi: CategoricalNB, kategorik özelliklere sahip veri kümeleri için özel olarak tasarlanmıştır. Metinsel verileri ve diğer ayrık özellik türlerini verimli bir şekilde işleyebilir.
- Temel performans: Genellikle metin sınıflandırma görevleri için güçlü bir temel model olarak hizmet eder ve küçük veri kümelerinde daha karmaşık algoritmalardan daha iyi performans gösterebilir.
CategoricalNB'nin sınırlamaları:
- Bağımsızlık varsayımı: Özellik bağımsızlığı varsayımı tüm veri kümeleri için geçerli olmayabilir. Özellikler yüksek oranda bağımlıysa CategoricalNB'nin performansı düşebilir.
- Özellik ölçeklendirmesine duyarlılık. CategoricalNB, kategorik verilerle çalıştığı için özellik ölçeklendirmesi gerektirmez. Ancak bazı durumlarda kategorik özelliklerin normalleştirilmesi veya farklı şekillerde kodlanması performansını etkileyebilir.
- Sınırlı ifade gücü: CategoricalNB, karmaşık veri bağımlılıklarını derin öğrenme modelleri gibi daha karmaşık algoritmalar kadar iyi yakalayamayabilir.
- Eksik verilerin işlenmesi: Veri kümesinde eksik değer olmadığını ve eksik değerlerin ön işlemeden geçirilmesi gerektiğini varsayar.
CategoricalNB, özellikle kategorik özelliklere sahip veri kümeleri için uygun olan değerli bir sınıflandırma algoritmasıdır. Basitliği, verimliliği ve yorumlanabilirliği onu çeşitli sınıflandırma görevleri için kullanışlı bir araç haline getirmektedir. Bağımsızlık varsayımı gibi sınırlamalara rağmen, metin sınıflandırması ve ayrık verilerin baskın olduğu diğer görevler için popüler bir seçim olmaya devam etmektedir. Kategorik verilerle çalışırken, CategoricalNB'yi temel model olarak düşünmek genellikle makul bir seçimdir. Bununla birlikte, özellikle verilerde özellik bağımlılıkları varsa, daha karmaşık modellere kıyasla performansını değerlendirmek önemlidir.
2.25.1. CategoricalNB Classifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir CategoricalNB Classifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_CategoricalNBClassifier.py # The code demonstrates the process of training CategoricalNB Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.naive_bayes import CategoricalNB from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 a CategoricalNB model categorical_nb_model = CategoricalNB() # train the model on the entire dataset categorical_nb_model.fit(X, y) # predict classes for the entire dataset y_pred = categorical_nb_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of CategoricalNB model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(categorical_nb_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "categorical_nb_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of CategoricalNB model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.86 0.96 0.91 50
Python 2 0.95 0.84 0.89 50
Python
Python accuracy 0.93 150
Python macro avg 0.94 0.93 0.93 150
Python weighted avg 0.94 0.93 0.93 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\categorical_nb_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of CategoricalNB model in ONNX format: 0.9333333333333333
2.25.2. CategoricalNB Classifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_CategoricalNBClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "categorical_nb_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="CategoricalNBClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+Çıktı:
Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=102 FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=122 FAILED [class=1, true class=2] features=(5.60,2.80,4.90,2.00] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=124 FAILED [class=1, true class=2] features=(6.30,2.70,4.90,1.80] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=127 FAILED [class=1, true class=2] features=(6.20,2.80,4.80,1.80] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=128 FAILED [class=1, true class=2] features=(6.10,3.00,4.90,1.80] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=139 FAILED [class=1, true class=2] features=(6.00,3.00,4.80,1.80] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier sample=143 FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90] Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier correct results: 93.33% Iris_CategoricalNBClassifier (EURUSD,H1) model=CategoricalNBClassifier all samples accuracy=0.933333 Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier FAILED [class=1, true class=2] features=(6.30,2.70,4.90,1.80) Iris_CategoricalNBClassifier (EURUSD,H1) model:CategoricalNBClassifier FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90) Iris_CategoricalNBClassifier (EURUSD,H1) model=CategoricalNBClassifier batch test accuracy=0.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %93.33'tür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.25.3. CategoricalNB Classifier modelinin ONNX gösterimi
Şekil 39. Netron'da CategoricalNB Classifier modelinin ONNX gösterimi
ExtraTreeClassifier ve ExtraTreesClassifier modelleri hakkında not
ExtraTreeClassifier ve ExtraTreesClassifier iki farklı sınıflandırıcıdır ve temel farkları nasıl çalıştıklarında yatmaktadır:
ExtraTreeClassifier (Extremely Randomized Trees Classifier):
- Bu sınıflandırıcı, Extremely Randomized Trees veya Extra-Trees olarak da bilinir.
- Rastgele karar ağaçları fikrine dayanmaktadır.
- ExtraTreeClassifier'da, her ağaç düğümü için bölme seçimi, en iyi bölme için önceden herhangi bir arama yapılmadan rastgele gerçekleşir.
- Bu, sınıflandırıcıyı klasik Random Forest'tan daha az hesaplama yoğun hale getirir çünkü her düğüm için optimum bölünmelerin hesaplanmasını gerektirmez.
- ExtraTreeClassifier genellikle özellikler için rastgele eşikler ve rastgele bölme kullanır, bu da daha rastgele ağaçlarla sonuçlanır.
- En iyi bölünmeler için bir arama yapılmaması, ExtraTreeClassifier'ı Random Forest'a kıyasla daha hızlı ancak daha az doğru yapar.
ExtraTreesClassifier (Extremely Randomized Trees Classifier):
- ExtraTreesClassifier da Extremely Randomized Trees yöntemine dayalı bir sınıflandırıcıdır.
- ExtraTreesClassifier ile ExtraTreeClassifier arasındaki temel fark, ExtraTreesClassifier'ın her ağaç düğümünde en iyi bölünmeleri seçmek için rastgele bölünmeler gerçekleştirmesidir.
- Bu, ExtraTreesClassifier'ın optimum bölünmeleri seçerken ek bir rastgelelik seviyesine sahip bir rastgele orman uyguladığı anlamına gelir.
- ExtraTreesClassifier genellikle ExtraTreeClassifier'dan daha doğrudur çünkü bölme için en iyi özellikleri bulmak için rastgele bölmeler gerçekleştirir.
- Bununla birlikte, ExtraTreesClassifier, optimum bölmeler için daha geniş bir arama yapma ihtiyacı nedeniyle hesaplama açısından daha yoğun olabilir.
Özetle, bu iki sınıflandırıcı arasındaki temel fark, bölünme seçimindeki rastgelelik seviyesinde yatmaktadır. ExtraTreeClassifier en iyi bölünmeleri aramadan her düğüm için rastgele bir seçim yaparken, ExtraTreesClassifier her düğümde en uygun bölünmeleri ararken rastgele bölünmeler gerçekleştirir.
2.26. ExtraTreeClassifier
ExtraTreeClassifier'ın prensipleri:
- Rastgele düğüm bölünmeleri: ExtraTreeClassifier'ın ana prensibi, her ağaç düğümü için bölünmeyi rastgele seçmesidir. Bu, bölme için en iyi özelliği seçen geleneksel karar ağaçlarından farklıdır. ExtraTreeClassifier, en iyi bölünmeyi dikkate almadan bölünmeleri gerçekleştirir, bu da onu daha rastgele ve aşırı uyuma karşı dirençli hale getirir.
- Sonuçların birleştirilmesi: Topluluk oluşturma sırasında, ExtraTreeClassifier birden fazla rastgele ağaç oluşturur ve bunların sonuçlarını toplar. Bu, modelin genellemesini iyileştirmek ve varyansı azaltmak için yapılır. Bir ağaç topluluğu, aşırı uyumla mücadeleye yardımcı olur ve tahmin kararlılığını artırır.
- Rastgele eşikler: ExtraTreeClassifier, düğümleri ayırırken belirli optimum değerler yerine her özellik için rastgele eşikler seçer. Bu, daha fazla rastgelelik ve model istikrarı sağlar.
- Aşırı uyuma karşı direnç: Rastgele bölünmeler ve en iyi bölünme seçiminin olmaması sayesinde ExtraTreeClassifier, normal karar ağaçlarına kıyasla genellikle aşırı uyum sağlamaya daha az eğilimlidir.
- Yüksek eğitim hızı: ExtraTreeClassifier, eğitim için rastgele ormanlar gibi diğer birçok algoritmadan daha az hesaplama kaynağı gerektirir. Bu, büyük veri kümeleri için hızlı ve verimli olmasını sağlar.
- Çok yönlülük: ExtraTreeClassifier hem sınıflandırma hem de regresyon görevleri için kullanılabilir, bu da onu çeşitli problem türleri için çok yönlü bir algoritma haline getirir.
- Rastgelelik: Rastgele bölünmelerin kullanılması bazı durumlarda daha az doğru modellere yol açabilir. Dikkatli parametre ayarı önemlidir.
- Aykırı değerlere hassasiyet: ExtraTreeClassifier rastgele bölünmeler oluşturduğundan verilerdeki aykırı değerlere karşı hassas olabilir. Bu, bazı durumlarda istikrarsız tahminlere yol açabilir.
- Daha düşük yorumlanabilirlik: Normal karar ağaçlarıyla karşılaştırıldığında, ExtraTreeClassifier daha az yorumlanabilir ve açıklaması daha zordur.
2.26.1. ExtraTreeClassifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir ExtraTreeClassifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_ExtraTreeClassifier.py # The code demonstrates the process of training ExtraTree Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.tree import ExtraTreeClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 an ExtraTreeClassifier model extra_tree_model = ExtraTreeClassifier() # train the model on the entire dataset extra_tree_model.fit(X, y) # predict classes for the entire dataset y_pred = extra_tree_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of ExtraTreeClassifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(extra_tree_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "extra_tree_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of ExtraTreeClassifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 1.00 1.00 50
Python 2 1.00 1.00 1.00 50
Python
Python accuracy 1.00 150
Python macro avg 1.00 1.00 1.00 150
Python weighted avg 1.00 1.00 1.00 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\extra_tree_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of ExtraTreeClassifier model in ONNX format: 1.0
2.26.2. ExtraTreeClassifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_ExtraTreeClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "extra_tree_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="ExtraTreeClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_ExtraTreeClassifier (EURUSD,H1) model:ExtraTreeClassifier correct results: 100.00% Iris_ExtraTreeClassifier (EURUSD,H1) model=ExtraTreeClassifier all samples accuracy=1.000000 Iris_ExtraTreeClassifier (EURUSD,H1) model=ExtraTreeClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %100'dür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.26.3. ExtraTreeClassifier modelinin ONNX gösterimi
Şekil 40. Netron'da ExtraTreeClassifier modelinin ONNX gösterimi
2.27. ExtraTreesClassifier
ExtraTreesClassifier, sınıflandırma görevleri için kullanılan güçlü bir makine öğrenimi algoritmasıdır. Bu algoritma, çeşitli avantajlar ve dezavantajlar sunan Random Forest'ın bir uzantısı ve geliştirmesidir.ExtraTreesClassifier’ın prensipleri:
- Yeniden örnekleme: Random Forest'a benzer şekilde ExtraTreesClassifier, eğitim veri kümesinden birden fazla alt örneklem oluşturmak için yeniden örnekleme yöntemini kullanır. Bu, her ağaç için orijinal verilerden değiştirmeli rastgele bir alt örneklem oluşturulduğu anlamına gelir.
- Rastgele bölünmeler: Her ağaç düğümü için bölme için en iyi özelliğin seçildiği Random Forest'ın aksine, ExtraTreesClassifier düğümleri bölmek için rastgele özellikler ve rastgele eşikler kullanır. Bu, ağaçları daha rastgele hale getirir ve aşırı uyumu azaltır.
- Oylama: Bir dizi ağaç oluşturulduktan sonra, her ağaç nesnenin sınıfı için oy kullanır. Nihayetinde, en çok oyu alan sınıf tahmin edilen sınıf olur.
- Azaltılmış aşırı uyum: Rastgele bölünmelerin ve rastgele özelliklerin kullanılması, ExtraTreesClassifier'ı geleneksel karar ağaçlarına kıyasla aşırı uyum sağlamaya daha az eğilimli hale getirir.
- Yüksek eğitim hızı: ExtraTreesClassifier, gradyan artırma gibi diğer bazı algoritmalara kıyasla eğitim için daha az hesaplama kaynağı gerektirir. Bu, özellikle büyük veri kümeleri için hızlı ve verimli olmasını sağlar.
- Aykırı değer sağlamlığı: Ağaç topluluğu ve rastgele bölünmeler sayesinde, ExtraTreesClassifier genellikle verilerdeki aykırı değerlere karşı daha sağlamdır.
- Karmaşık yorumlanabilirlik: Bir ExtraTreesClassifier modelini analiz etmek ve yorumlamak, çok sayıda rastgele bölünme ve özellik nedeniyle zor olabilir.
- Parametre ayarlama: Verimliliğine rağmen, ExtraTreesClassifier optimum performans elde etmek için dikkatli hiperparametre ayarı gerektirebilir.
- Her zaman en iyi performansa sahip değildir: Bazı görevlerde ExtraTreesClassifier, gradyan artırma gibi diğer algoritmalardan daha az doğru olabilir.
2.27.1. ExtraTreesClassifier modelini oluşturmak için kod
Bu kod, iris veri kümesi üzerinde bir ExtraTreesClassifier modelinin eğitilmesi, ONNX formatına aktarılması ve ONNX modeli kullanılarak sınıflandırma yapılması sürecini göstermektedir. Ayrıca hem orijinal modelin hem de ONNX modelinin doğruluğunu değerlendirir.
# Iris_ExtraTreesClassifier.py # The code demonstrates the process of training ExtraTrees Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model. # It also evaluates the accuracy of both the original model and the ONNX model. # Copyright 2023, MetaQuotes Ltd. # https://www.mql5.com # import necessary libraries from sklearn import datasets from sklearn.ensemble import ExtraTreesClassifier from sklearn.metrics import accuracy_score, classification_report from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType import onnxruntime as ort import numpy as np 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 an ExtraTreesClassifier model extra_trees_model = ExtraTreesClassifier() # train the model on the entire dataset extra_trees_model.fit(X, y) # predict classes for the entire dataset y_pred = extra_trees_model.predict(X) # evaluate the model's accuracy accuracy = accuracy_score(y, y_pred) print("Accuracy of ExtraTreesClassifier model:", accuracy) # display the classification report print("\nClassification Report:\n", classification_report(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(extra_trees_model, initial_types=initial_type, target_opset=12) # save the model to a file onnx_filename = data_path + "extra_trees_iris.onnx" with open(onnx_filename, "wb") as f: f.write(onnx_model.SerializeToString()) # print model path print(f"Model saved to {onnx_filename}") # 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 # display information about input tensors in ONNX print("\nInformation about input tensors in ONNX:") for i, input_tensor in enumerate(onnx_session.get_inputs()): print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}") # display information about output tensors in ONNX print("\nInformation about output tensors in ONNX:") for i, output_tensor in enumerate(onnx_session.get_outputs()): print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}") # 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) print("\nAccuracy of ExtraTreesClassifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 1.00 1.00 50
Python 2 1.00 1.00 1.00 50
Python
Python accuracy 1.00 150
Python macro avg 1.00 1.00 1.00 150
Python weighted avg 1.00 1.00 1.00 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\extra_trees_iris.onnx
Python
Python Information about input tensors in ONNX:
Python 1. Name: float_input, Data Type: tensor(float), Shape: [None, 4]
Python
Python Information about output tensors in ONNX:
Python 1. Name: output_label, Data Type: tensor(int64), Shape: [None]
Python 2. Name: output_probability, Data Type: seq(map(int64,tensor(float))), Shape: []
Python
Python Accuracy of ExtraTreesClassifier model in ONNX format: 1.0
2.27.2. ExtraTreesClassifier modeliyle çalışmak için MQL5 kodu
//+------------------------------------------------------------------+ //| Iris_ExtraTreesClassifier.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" #resource "extra_trees_iris.onnx" as const uchar ExtModel[]; //+------------------------------------------------------------------+ //| Test IRIS dataset samples | //+------------------------------------------------------------------+ bool TestSamples(long model,float &input_data[][4], int &model_classes_id[]) { //--- check number of input samples ulong batch_size=input_data.Range(0); if(batch_size==0) return(false); //--- prepare output array ArrayResize(model_classes_id,(int)batch_size); //--- float output_data[]; //--- struct Map { ulong key[]; float value[]; } output_data_map[]; //--- check consistency bool res=ArrayResize(output_data,(int)batch_size)==batch_size; //--- if(res) { //--- set input shape ulong input_shape[]= {batch_size,input_data.Range(1)}; OnnxSetInputShape(model,0,input_shape); //--- set output shapeы ulong output_shape1[]= {batch_size}; ulong output_shape2[]= {batch_size}; OnnxSetOutputShape(model,0,output_shape1); OnnxSetOutputShape(model,1,output_shape2); //--- run the model res=OnnxRun(model,0,input_data,output_data,output_data_map); //--- postprocessing if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- for(uint n=0; n<output_data_map.Size(); n++) { int model_class_id=-1; int max_idx=-1; float max_value=-1; //--- copy to arrays ArrayCopy(output_keys,output_data_map[n].key); ArrayCopy(output_values,output_data_map[n].value); //ArrayPrint(output_keys); //ArrayPrint(output_values); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } //--- store the result to the output array model_classes_id[n]=model_class_id; //Print("model_class_id=",model_class_id); } } } //--- return(res); } //+------------------------------------------------------------------+ //| Test all samples from IRIS dataset (150) | //| Here we test all samples with batch=1, sample by sample | //+------------------------------------------------------------------+ bool TestAllIrisDataset(const long model,const string model_name,double &model_accuracy) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("iris dataset not prepared"); return(false); } //--- show dataset for(int k=0; k<total_samples; k++) { //PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); } //--- array for output classes int model_output_classes_id[]; //--- check all Iris dataset samples int correct_results=0; for(int k=0; k<total_samples; k++) { //--- input array float iris_sample_input_data[1][4]; //--- prepare input data from kth iris sample dataset iris_sample_input_data[0][0]=(float)iris_samples[k].features[0]; iris_sample_input_data[0][1]=(float)iris_samples[k].features[1]; iris_sample_input_data[0][2]=(float)iris_samples[k].features[2]; iris_sample_input_data[0][3]=(float)iris_samples[k].features[3]; //--- run model bool res=TestSamples(model,iris_sample_input_data,model_output_classes_id); //--- check result if(res) { if(model_output_classes_id[0]==iris_samples[k].class_id) { correct_results++; } else { PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_output_classes_id[0],iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } } model_accuracy=1.0*correct_results/total_samples; //--- PrintFormat("model:%s correct results: %.2f%%",model_name,100*model_accuracy); //--- return(true); } //+------------------------------------------------------------------+ //| Here we test batch execution of the model | //+------------------------------------------------------------------+ bool TestBatchExecution(const long model,const string model_name,double &model_accuracy) { model_accuracy=0; //--- array for output classes int model_output_classes_id[]; int correct_results=0; int total_results=0; bool res=false; //--- run batch with 3 samples float input_data_batch3[3][4]= { {5.1f,3.5f,1.4f,0.2f}, // iris dataset sample id=1, Iris-setosa {6.3f,2.5f,4.9f,1.5f}, // iris dataset sample id=73, Iris-versicolor {6.3f,2.7f,4.9f,1.8f} // iris dataset sample id=124, Iris-virginica }; int correct_classes_batch3[3]= {0,1,2}; //--- run model res=TestSamples(model,input_data_batch3,model_output_classes_id); if(res) { //--- check result for(int j=0; j<ArraySize(model_output_classes_id); j++) { //--- check result if(model_output_classes_id[j]==correct_classes_batch3[j]) correct_results++; else { PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch3[j],input_data_batch3[j][0],input_data_batch3[j][1],input_data_batch3[j][2],input_data_batch3[j][3]); } total_results++; } } else return(false); //--- run batch with 10 samples float input_data_batch10[10][4]= { {5.5f,3.5f,1.3f,0.2f}, // iris dataset sample id=37 (Iris-setosa) {4.9f,3.1f,1.5f,0.1f}, // iris dataset sample id=38 (Iris-setosa) {4.4f,3.0f,1.3f,0.2f}, // iris dataset sample id=39 (Iris-setosa) {5.0f,3.3f,1.4f,0.2f}, // iris dataset sample id=50 (Iris-setosa) {7.0f,3.2f,4.7f,1.4f}, // iris dataset sample id=51 (Iris-versicolor) {6.4f,3.2f,4.5f,1.5f}, // iris dataset sample id=52 (Iris-versicolor) {6.3f,3.3f,6.0f,2.5f}, // iris dataset sample id=101 (Iris-virginica) {5.8f,2.7f,5.1f,1.9f}, // iris dataset sample id=102 (Iris-virginica) {7.1f,3.0f,5.9f,2.1f}, // iris dataset sample id=103 (Iris-virginica) {6.3f,2.9f,5.6f,1.8f} // iris dataset sample id=104 (Iris-virginica) }; //--- correct classes for all 10 samples in the batch int correct_classes_batch10[10]= {0,0,0,0,1,1,2,2,2,2}; //--- run model res=TestSamples(model,input_data_batch10,model_output_classes_id); //--- check result if(res) { for(int j=0; j<ArraySize(model_output_classes_id); j++) { if(model_output_classes_id[j]==correct_classes_batch10[j]) correct_results++; else { double f1=input_data_batch10[j][0]; double f2=input_data_batch10[j][1]; double f3=input_data_batch10[j][2]; double f4=input_data_batch10[j][3]; PrintFormat("model:%s FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f)",model_name,model_output_classes_id[j],correct_classes_batch10[j],input_data_batch10[j][0],input_data_batch10[j][1],input_data_batch10[j][2],input_data_batch10[j][3]); } total_results++; } } else return(false); //--- calculate accuracy model_accuracy=correct_results/total_results; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { string model_name="ExtraTreesClassifier"; //--- long model=OnnxCreateFromBuffer(ExtModel,ONNX_DEFAULT); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- test all dataset double model_accuracy=0; //-- test sample by sample execution for all Iris dataset if(TestAllIrisDataset(model,model_name,model_accuracy)) PrintFormat("model=%s all samples accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- test batch execution for several samples if(TestBatchExecution(model,model_name,model_accuracy)) PrintFormat("model=%s batch test accuracy=%f",model_name,model_accuracy); else PrintFormat("error in testing model=%s ",model_name); //--- release model OnnxRelease(model); } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_ExtraTreesClassifier (EURUSD,H1) model:ExtraTreesClassifier correct results: 100.00% Iris_ExtraTreesClassifier (EURUSD,H1) model=ExtraTreesClassifier all samples accuracy=1.000000 Iris_ExtraTreesClassifier (EURUSD,H1) model=ExtraTreesClassifier batch test accuracy=1.000000
Dışa aktarılan ONNX modelinin tam iris veri kümesi üzerindeki doğruluğu %100'dür ve bu da orijinal modelin doğruluğuna karşılık gelmektedir.
2.27.3. ExtraTreesClassifier modelinin ONNX gösterimi
Şekil 41. Netron'da ExtraTreesClassifier modelinin ONNX gösterimi
2.28. Tüm modellerin doğruluğunun karşılaştırılması
Şimdi tüm modelleri birlikte ele alalım ve performanslarını karşılaştıralım. İlk olarak, Python kullanarak karşılaştırmayı gerçekleştireceğiz ve ardından kaydedilen ONNX modellerini MetaTrader 5'e yükleyip çalıştıracağız.
2.28.1. Tüm modelleri hesaplamak ve bir doğruluk karşılaştırma grafiği oluşturmak için kod
Bu komut dosyası, Fisher'ın iris veri setinin tamamı üzerinde Scikit-learn paketinden 27 sınıflandırma modeli hesaplar, modelleri ONNX formatına aktarır, yürütür ve orijinal ve ONNX modellerinin doğruluğunu karşılaştırır.
# 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()
Çıktı:
Python Sorted Results: Python Random Forest Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 Python Gradient Boosting Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 Python Bagging Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 Python Decision Tree Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 Python Extra Tree Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 Python Extra Trees Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 Python Hist Gradient Boosting Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 Python Logistic RegressionCV Classifier - Original Accuracy: 0.9800, ONNX Accuracy: 0.9800 Python MLP Classifier - Original Accuracy: 0.9800, ONNX Accuracy: 0.9800 Python Linear Discriminant Analysis Classifier - Original Accuracy: 0.9800, ONNX Accuracy: 0.9800 Python SVC Classifier - Original Accuracy: 0.9733, ONNX Accuracy: 0.9733 Python Radius Neighbors Classifier - Original Accuracy: 0.9733, ONNX Accuracy: 0.9733 Python Logistic Regression Classifier - Original Accuracy: 0.9733, ONNX Accuracy: 0.9733 Python NuSVC Classifier - Original Accuracy: 0.9733, ONNX Accuracy: 0.9733 Python K-NN Classifier - Original Accuracy: 0.9667, ONNX Accuracy: 0.9667 Python LinearSVC Classifier - Original Accuracy: 0.9667, ONNX Accuracy: 0.9667 Python AdaBoost Classifier - Original Accuracy: 0.9600, ONNX Accuracy: 0.9600 Python Passive-Aggressive Classifier - Original Accuracy: 0.9600, ONNX Accuracy: 0.9600 Python Gaussian Naive Bayes Classifier - Original Accuracy: 0.9600, ONNX Accuracy: 0.9600 Python Multinomial Naive Bayes Classifier - Original Accuracy: 0.9533, ONNX Accuracy: 0.9533 Python SGD Classifier - Original Accuracy: 0.9333, ONNX Accuracy: 0.9333 Python Categorical Naive Bayes Classifier - Original Accuracy: 0.9333, ONNX Accuracy: 0.9333 Python Ridge Classifier - Original Accuracy: 0.8533, ONNX Accuracy: 0.8533 Python Ridge ClassifierCV - Original Accuracy: 0.8533, ONNX Accuracy: 0.8533 Python Complement Naive Bayes Classifier - Original Accuracy: 0.6667, ONNX Accuracy: 0.6667 Python Perceptron Classifier - Original Accuracy: 0.6133, ONNX Accuracy: 0.6133 Python Bernoulli Naive Bayes Classifier - Original Accuracy: 0.3333, ONNX Accuracy: 0.3333Komut dosyası ayrıca 27 modelin tümü için özet sonuçları içeren bir görüntü oluşturacaktır.
Şekil 42. İris veri kümesi üzerinde 27 sınıflandırma modeli ve bunların ONNX versiyonları için doğruluk karşılaştırması
Orijinal modellerin ve ONNX versiyonlarının doğruluk değerlendirme sonuçlarına dayanarak aşağıdaki sonuçlar çıkarılabilir:
Yedi model hem orijinal hem de ONNX versiyonlarında mükemmel doğruluk (1.0000) göstermiştir. Bu modeller şunlardır:
- Random Forest Classifier
- Gradient Boosting Classifier
- Bagging Classifier
- Decision Tree Classifier
- Extra Tree Classifier
- Extra Trees Classifier
- Hist Gradient Boosting Classifier
Bu modellerin ONNX temsilleri de yüksek doğruluğu korumaktadır.
Üç model (Logistic RegressionCV Classifier, MLP Classifier ve Linear Discriminant Analysis Classifier) hem orijinal hem de ONNX versiyonlarında 0.9800 doğrulukla yüksek doğruluk elde etmiştir. Bu modeller her iki temsilde de iyi performans göstermektedir.
SVC Classifier, Radius Neighbors Classifier, NuSVC Classifier, K-NN Classifier, LinearSVC Classifier, AdaBoost Classifier, Passive-Aggressive Classifier, Gaussian Naive Bayes Classifier ve Multinomial Naive Bayes Classifier dahil olmak üzere çeşitli modeller, 0.9733, 0.9667 veya 0.9600 doğruluk puanlarıyla hem orijinal hem de ONNX sürümlerinde iyi doğruluk göstermiştir. Bu modeller ONNX gösteriminde de doğruluklarını korumaktadır.
SGD Classifier, Categorical Naive Bayes Classifier, Ridge Classifier, Complement Naive Bayes Classifier, Perceptron Classifier ve Bernoulli Naive Bayes Classifier gibi modeller daha düşük doğruluğa sahiptir, ancak yine de ONNX'te doğruluğu korumada iyi performans göstermektedir.
Ele alınan tüm modeller ONNX formatına aktarıldıklarında doğruluklarını korumaktadır; bu da ONNX'in makine öğrenimi modellerini kaydetmek ve geri yüklemek için etkili bir yol sağladığını göstermektedir. Ancak, dışa aktarılan modelin kalitesinin belirli model algoritmasına ve parametrelerine bağlı olabileceğini unutmamak önemlidir.
2.28.2. Tüm ONNX modellerini çalıştırmak için MQL5 kodu
Bu komut dosyası, 2.28.1'deki komut dosyası tarafından kaydedilen tüm ONNX modellerini Fisher'ın iris veri kümesinin tamamında çalıştırır.
//+------------------------------------------------------------------+ //| Iris_AllClassifiers.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include "iris.mqh" //+------------------------------------------------------------------+ //| TestSampleSequenceMapOutput | //+------------------------------------------------------------------+ bool TestSampleSequenceMapOutput(long model,sIRISsample &iris_sample, int &model_class_id) { //--- model_class_id=-1; float input_data[1][4]; for(int k=0; k<4; k++) { input_data[0][k]=(float)iris_sample.features[k]; } //--- float out1[]; //--- struct Map { ulong key[]; float value[]; } out2[]; //--- bool res=ArrayResize(out1,input_data.Range(0))==input_data.Range(0); //--- if(res) { ulong input_shape[]= { input_data.Range(0), input_data.Range(1) }; ulong output_shape[]= { input_data.Range(0) }; //--- OnnxSetInputShape(model,0,input_shape); OnnxSetOutputShape(model,0,output_shape); //--- res=OnnxRun(model,0,input_data,out1,out2); //--- if(res) { //--- postprocessing of sequence map data //--- find class with maximum probability ulong output_keys[]; float output_values[]; //--- model_class_id=-1; int max_idx=-1; float max_value=-1; //--- for(uint n=0; n<out2.Size(); n++) { //--- copy to arrays ArrayCopy(output_keys,out2[n].key); ArrayCopy(output_values,out2[n].value); //--- find the key with maximum probability for(int k=0; k<ArraySize(output_values); k++) { if(k==0) { max_idx=0; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } else { if(output_values[k]>max_value) { max_idx=k; max_value=output_values[max_idx]; model_class_id=(int)output_keys[max_idx]; } } } } } } //--- return(res); } //+------------------------------------------------------------------+ //| TestSampleTensorOutput | //+------------------------------------------------------------------+ bool TestSampleTensorOutput(long model,sIRISsample &iris_sample, int &model_class_id) { //--- model_class_id=-1; float input_data[1][4]; for(int k=0; k<4; k++) { input_data[0][k]=(float)iris_sample.features[k]; } //--- ulong input_shape[]= { 1, 4}; OnnxSetInputShape(model,0,input_shape); //--- int output1[1]; float output2[1,3]; //--- ulong output_shape[]= {1}; OnnxSetOutputShape(model,0,output_shape); //--- ulong output_shape2[]= {1,3}; OnnxSetOutputShape(model,1,output_shape2); //--- bool res=OnnxRun(model,0,input_data,output1,output2); //--- class for these models in output1[0]; if(res) model_class_id=output1[0]; //--- return(res); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart(void) { sIRISsample iris_samples[]; //--- load dataset from file PrepareIrisDataset(iris_samples); //--- test int total_samples=ArraySize(iris_samples); if(total_samples==0) { Print("error in loading iris dataset from iris.csv"); return(false); } /*for(int k=0; k<total_samples; k++) { PrintFormat("%d (%.2f,%.2f,%.2f,%.2f) class %d (%s)",iris_samples[k].sample_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3],iris_samples[k].class_id,iris_samples[k].class_name); }*/ //---- string iris_models[]= { "random_forest_classifier_iris.onnx", "gradient_boosting_classifier_iris.onnx", "bagging_classifier_iris.onnx", "decision_tree_classifier_iris.onnx", "extra_tree_classifier_iris.onnx", "extra_trees_classifier_iris.onnx", "hist_gradient_boosting_classifier_iris.onnx", "logistic_regressioncv_classifier_iris.onnx", "mlp_classifier_iris.onnx", "linear_discriminant_analysis_classifier_iris.onnx", "svc_classifier_iris.onnx", "radius_neighbors_classifier_iris.onnx", "logistic_regression_classifier_iris.onnx", "nusvc_classifier_iris.onnx", "k-nn_classifier_iris.onnx", "linearsvc_classifier_iris.onnx", "adaboost_classifier_iris.onnx", "passive-aggressive_classifier_iris.onnx", "gaussian_naive_bayes_classifier_iris.onnx", "multinomial_naive_bayes_classifier_iris.onnx", "sgd_classifier_iris.onnx", "categorical_naive_bayes_classifier_iris.onnx", "ridge_classifier_iris.onnx", "ridge_classifiercv_iris.onnx", "complement_naive_bayes_classifier_iris.onnx", "perceptron_classifier_iris.onnx", "bernoulli_naive_bayes_classifier_iris.onnx" }; //--- test all iris dataset sample by sample for(int i=0; i<ArraySize(iris_models); i++) { //--- load ONNX-model string model_name="IRIS_models\\"+iris_models[i]; //--- long model=OnnxCreate(model_name,0); if(model==INVALID_HANDLE) { PrintFormat("model_name=%s OnnxCreate error %d for",model_name,GetLastError()); } else { //--- check all samples int correct_results=0; for(int k=0; k<total_samples; k++) { int model_class_id=-1; //--- select data output processor string current_model=iris_models[i]; if(current_model=="svc_classifier_iris.onnx" || current_model=="linearsvc_classifier_iris.onnx" || current_model=="nusvc_classifier_iris.onnx" || current_model=="ridge_classifier_iris.onnx" || current_model=="ridge_classifiercv_iris.onnx" || current_model=="radius_neighbors_classifier_iris.onnx") { TestSampleTensorOutput(model,iris_samples[k],model_class_id); } else { TestSampleSequenceMapOutput(model,iris_samples[k],model_class_id); } //--- if(model_class_id==iris_samples[k].class_id) { correct_results++; //PrintFormat("sample=%d OK [class=%d]",iris_samples[k].sample_id,model_class_id); } else { //PrintFormat("model:%s sample=%d FAILED [class=%d, true class=%d] features=(%.2f,%.2f,%.2f,%.2f]",model_name,iris_samples[k].sample_id,model_class_id,iris_samples[k].class_id,iris_samples[k].features[0],iris_samples[k].features[1],iris_samples[k].features[2],iris_samples[k].features[3]); } } PrintFormat("%d model:%s accuracy: %.4f",i+1,model_name,1.0*correct_results/total_samples); //--- release model OnnxRelease(model); } //--- } return(0); } //+------------------------------------------------------------------+
Çıktı:
Iris_AllClassifiers (EURUSD,H1) 1 model:IRIS_models\random_forest_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 2 model:IRIS_models\gradient_boosting_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 3 model:IRIS_models\bagging_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 4 model:IRIS_models\decision_tree_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 5 model:IRIS_models\extra_tree_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 6 model:IRIS_models\extra_trees_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 7 model:IRIS_models\hist_gradient_boosting_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 8 model:IRIS_models\logistic_regressioncv_classifier_iris.onnx accuracy: 0.9800 Iris_AllClassifiers (EURUSD,H1) 9 model:IRIS_models\mlp_classifier_iris.onnx accuracy: 0.9800 Iris_AllClassifiers (EURUSD,H1) 10 model:IRIS_models\linear_discriminant_analysis_classifier_iris.onnx accuracy: 0.9800 Iris_AllClassifiers (EURUSD,H1) 11 model:IRIS_models\svc_classifier_iris.onnx accuracy: 0.9733 Iris_AllClassifiers (EURUSD,H1) 12 model:IRIS_models\radius_neighbors_classifier_iris.onnx accuracy: 0.9733 Iris_AllClassifiers (EURUSD,H1) 13 model:IRIS_models\logistic_regression_classifier_iris.onnx accuracy: 0.9733 Iris_AllClassifiers (EURUSD,H1) 14 model:IRIS_models\nusvc_classifier_iris.onnx accuracy: 0.9733 Iris_AllClassifiers (EURUSD,H1) 15 model:IRIS_models\k-nn_classifier_iris.onnx accuracy: 0.9667 Iris_AllClassifiers (EURUSD,H1) 16 model:IRIS_models\linearsvc_classifier_iris.onnx accuracy: 0.9667 Iris_AllClassifiers (EURUSD,H1) 17 model:IRIS_models\adaboost_classifier_iris.onnx accuracy: 0.9600 Iris_AllClassifiers (EURUSD,H1) 18 model:IRIS_models\passive-aggressive_classifier_iris.onnx accuracy: 0.9600 Iris_AllClassifiers (EURUSD,H1) 19 model:IRIS_models\gaussian_naive_bayes_classifier_iris.onnx accuracy: 0.9600 Iris_AllClassifiers (EURUSD,H1) 20 model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx accuracy: 0.9533 Iris_AllClassifiers (EURUSD,H1) 21 model:IRIS_models\sgd_classifier_iris.onnx accuracy: 0.9333 Iris_AllClassifiers (EURUSD,H1) 22 model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx accuracy: 0.9333 Iris_AllClassifiers (EURUSD,H1) 23 model:IRIS_models\ridge_classifier_iris.onnx accuracy: 0.8533 Iris_AllClassifiers (EURUSD,H1) 24 model:IRIS_models\ridge_classifiercv_iris.onnx accuracy: 0.8533 Iris_AllClassifiers (EURUSD,H1) ONNX: Removing initializer 'class_log_prior'. It is not used by any node and should be removed from the model. Iris_AllClassifiers (EURUSD,H1) 25 model:IRIS_models\complement_naive_bayes_classifier_iris.onnx accuracy: 0.6667 Iris_AllClassifiers (EURUSD,H1) 26 model:IRIS_models\perceptron_classifier_iris.onnx accuracy: 0.6133 Iris_AllClassifiers (EURUSD,H1) 27 model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx accuracy: 0.3333
Kod 2.28.1'deki sonuçlar ile karşılaştırma:
Python Random Forest Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 1 model:IRIS_models\random_forest_classifier_iris.onnx accuracy: 1.0000 Python Gradient Boosting Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 2 model:IRIS_models\gradient_boosting_classifier_iris.onnx accuracy: 1.0000 Python Bagging Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 3 model:IRIS_models\bagging_classifier_iris.onnx accuracy: 1.0000 Python Decision Tree Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 4 model:IRIS_models\decision_tree_classifier_iris.onnx accuracy: 1.0000 Python Extra Tree Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 5 model:IRIS_models\extra_tree_classifier_iris.onnx accuracy: 1.0000 Python Extra Trees Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 6 model:IRIS_models\extra_trees_classifier_iris.onnx accuracy: 1.0000 Python Hist Gradient Boosting Classifier - Original Accuracy: 1.0000, ONNX Accuracy: 1.0000 7 model:IRIS_models\hist_gradient_boosting_classifier_iris.onnx accuracy: 1.0000 Python Logistic RegressionCV Classifier - Original Accuracy: 0.9800, ONNX Accuracy: 0.9800 8 model:IRIS_models\logistic_regressioncv_classifier_iris.onnx accuracy: 0.9800 Python MLP Classifier - Original Accuracy: 0.9800, ONNX Accuracy: 0.9800 9 model:IRIS_models\mlp_classifier_iris.onnx accuracy: 0.9800 Python Linear Discriminant Analysis Classifier - Original Accuracy: 0.9800, ONNX Accuracy: 0.9800 10 model:IRIS_models\linear_discriminant_analysis_classifier_iris.onnx accuracy: 0.9800 Python SVC Classifier - Original Accuracy: 0.9733, ONNX Accuracy: 0.9733 11 model:IRIS_models\svc_classifier_iris.onnx accuracy: 0.9733 Python Radius Neighbors Classifier - Original Accuracy: 0.9733, ONNX Accuracy: 0.9733 12 model:IRIS_models\radius_neighbors_classifier_iris.onnx accuracy: 0.9733 Python Logistic Regression Classifier - Original Accuracy: 0.9733, ONNX Accuracy: 0.9733 13 model:IRIS_models\logistic_regression_classifier_iris.onnx accuracy: 0.9733 Python NuSVC Classifier - Original Accuracy: 0.9733, ONNX Accuracy: 0.9733 14 model:IRIS_models\nusvc_classifier_iris.onnx accuracy: 0.9733 Python K-NN Classifier - Original Accuracy: 0.9667, ONNX Accuracy: 0.9667 15 model:IRIS_models\k-nn_classifier_iris.onnx accuracy: 0.9667 Python LinearSVC Classifier - Original Accuracy: 0.9667, ONNX Accuracy: 0.9667 16 model:IRIS_models\linearsvc_classifier_iris.onnx accuracy: 0.9667 Python AdaBoost Classifier - Original Accuracy: 0.9600, ONNX Accuracy: 0.9600 17 model:IRIS_models\adaboost_classifier_iris.onnx accuracy: 0.9600 Python Passive-Aggressive Classifier - Original Accuracy: 0.9600, ONNX Accuracy: 0.9600 18 model:IRIS_models\passive-aggressive_classifier_iris.onnx accuracy: 0.9600 Python Gaussian Naive Bayes Classifier - Original Accuracy: 0.9600, ONNX Accuracy: 0.9600 19 model:IRIS_models\gaussian_naive_bayes_classifier_iris.onnx accuracy: 0.9600 Python Multinomial Naive Bayes Classifier - Original Accuracy: 0.9533, ONNX Accuracy: 0.9533 20 model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx accuracy: 0.9533 Python SGD Classifier - Original Accuracy: 0.9333, ONNX Accuracy: 0.9333 21 model:IRIS_models\sgd_classifier_iris.onnx accuracy: 0.9333 Python Categorical Naive Bayes Classifier - Original Accuracy: 0.9333, ONNX Accuracy: 0.9333 22 model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx accuracy: 0.9333 Python Ridge Classifier - Original Accuracy: 0.8533, ONNX Accuracy: 0.8533 23 model:IRIS_models\ridge_classifier_iris.onnx accuracy: 0.8533 Python Ridge ClassifierCV - Original Accuracy: 0.8533, ONNX Accuracy: 0.8533 24 model:IRIS_models\ridge_classifiercv_iris.onnx accuracy: 0.8533 Python Complement Naive Bayes Classifier - Original Accuracy: 0.6667, ONNX Accuracy: 0.6667 25 model:IRIS_models\complement_naive_bayes_classifier_iris.onnx accuracy: 0.6667 Python Perceptron Classifier - Original Accuracy: 0.6133, ONNX Accuracy: 0.6133 26 model:IRIS_models\perceptron_classifier_iris.onnx accuracy: 0.6133 Python Bernoulli Naive Bayes Classifier - Original Accuracy: 0.3333, ONNX Accuracy: 0.3333 27 model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx accuracy: 0.3333
Kaydedilen tüm ONNX modellerinin MQL5'te çalıştırılmasının 2.28.1'deki sonuçlara tamamen karşılık geldiğini belirtmek gerekir.
Böylece, incelediğimiz modeller ONNX formatına dönüştürüldüğünde sınıflandırma doğruluklarını korumuşlardır.
Yedi modelin iris veri kümesi için mükemmel sınıflandırma doğruluğu (accuracy=1.0) elde ettiğini belirtmek gerekir:
- Random Forest Classifier;
- Gradient Boosting Classifier;
- Bagging Classifier;
- Decision Tree Classifier;
- Extra Tree Classifier;
- Extra Trees Classifier;
- Histogram Gradient Boosting Classifier.
Kalan 20 model sınıflandırma hatası yapmıştır.
208. satırı yorumdan kaldırırsanız, komut dosyası her bir model tarafından yanlış sınıflandırılan iris veri kümesi örneklerini de görüntüler:
Iris_AllClassifiers (EURUSD,H1) 1 model:IRIS_models\random_forest_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 2 model:IRIS_models\gradient_boosting_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 3 model:IRIS_models\bagging_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 4 model:IRIS_models\decision_tree_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 5 model:IRIS_models\extra_tree_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 6 model:IRIS_models\extra_trees_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) 7 model:IRIS_models\hist_gradient_boosting_classifier_iris.onnx accuracy: 1.0000 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\logistic_regressioncv_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\logistic_regressioncv_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\logistic_regressioncv_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) 8 model:IRIS_models\logistic_regressioncv_classifier_iris.onnx accuracy: 0.9800 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\mlp_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\mlp_classifier_iris.onnx sample=73 FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\mlp_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) 9 model:IRIS_models\mlp_classifier_iris.onnx accuracy: 0.9800 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\linear_discriminant_analysis_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\linear_discriminant_analysis_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\linear_discriminant_analysis_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) 10 model:IRIS_models\linear_discriminant_analysis_classifier_iris.onnx accuracy: 0.9800 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\svc_classifier_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\svc_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\svc_classifier_iris.onnx sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\svc_classifier_iris.onnx sample=139 FAILED [class=1, true class=2] features=(6.00,3.00,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) 11 model:IRIS_models\svc_classifier_iris.onnx accuracy: 0.9733 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\radius_neighbors_classifier_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\radius_neighbors_classifier_iris.onnx sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\radius_neighbors_classifier_iris.onnx sample=127 FAILED [class=1, true class=2] features=(6.20,2.80,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\radius_neighbors_classifier_iris.onnx sample=139 FAILED [class=1, true class=2] features=(6.00,3.00,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) 12 model:IRIS_models\radius_neighbors_classifier_iris.onnx accuracy: 0.9733 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\logistic_regression_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\logistic_regression_classifier_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\logistic_regression_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\logistic_regression_classifier_iris.onnx sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_AllClassifiers (EURUSD,H1) 13 model:IRIS_models\logistic_regression_classifier_iris.onnx accuracy: 0.9733 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\nusvc_classifier_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\nusvc_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\nusvc_classifier_iris.onnx sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\nusvc_classifier_iris.onnx sample=139 FAILED [class=1, true class=2] features=(6.00,3.00,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) 14 model:IRIS_models\nusvc_classifier_iris.onnx accuracy: 0.9733 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\k-nn_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\k-nn_classifier_iris.onnx sample=73 FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\k-nn_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\k-nn_classifier_iris.onnx sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\k-nn_classifier_iris.onnx sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_AllClassifiers (EURUSD,H1) 15 model:IRIS_models\k-nn_classifier_iris.onnx accuracy: 0.9667 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\linearsvc_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\linearsvc_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\linearsvc_classifier_iris.onnx sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\linearsvc_classifier_iris.onnx sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\linearsvc_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) 16 model:IRIS_models\linearsvc_classifier_iris.onnx accuracy: 0.9667 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\adaboost_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\adaboost_classifier_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\adaboost_classifier_iris.onnx sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\adaboost_classifier_iris.onnx sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\adaboost_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\adaboost_classifier_iris.onnx sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_AllClassifiers (EURUSD,H1) 17 model:IRIS_models\adaboost_classifier_iris.onnx accuracy: 0.9600 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\passive-aggressive_classifier_iris.onnx sample=67 FAILED [class=2, true class=1] features=(5.60,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\passive-aggressive_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\passive-aggressive_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\passive-aggressive_classifier_iris.onnx sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\passive-aggressive_classifier_iris.onnx sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\passive-aggressive_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) 18 model:IRIS_models\passive-aggressive_classifier_iris.onnx accuracy: 0.9600 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\gaussian_naive_bayes_classifier_iris.onnx sample=53 FAILED [class=2, true class=1] features=(6.90,3.10,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\gaussian_naive_bayes_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\gaussian_naive_bayes_classifier_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\gaussian_naive_bayes_classifier_iris.onnx sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\gaussian_naive_bayes_classifier_iris.onnx sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\gaussian_naive_bayes_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) 19 model:IRIS_models\gaussian_naive_bayes_classifier_iris.onnx accuracy: 0.9600 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx sample=69 FAILED [class=2, true class=1] features=(6.20,2.20,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx sample=73 FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx sample=132 FAILED [class=1, true class=2] features=(7.90,3.80,6.40,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) 20 model:IRIS_models\multinomial_naive_bayes_classifier_iris.onnx accuracy: 0.9533 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=65 FAILED [class=0, true class=1] features=(5.60,2.90,3.60,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=86 FAILED [class=0, true class=1] features=(6.00,3.40,4.50,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=124 FAILED [class=1, true class=2] features=(6.30,2.70,4.90,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=127 FAILED [class=1, true class=2] features=(6.20,2.80,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\sgd_classifier_iris.onnx sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_AllClassifiers (EURUSD,H1) 21 model:IRIS_models\sgd_classifier_iris.onnx accuracy: 0.9333 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=102 FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=122 FAILED [class=1, true class=2] features=(5.60,2.80,4.90,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=124 FAILED [class=1, true class=2] features=(6.30,2.70,4.90,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=127 FAILED [class=1, true class=2] features=(6.20,2.80,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=128 FAILED [class=1, true class=2] features=(6.10,3.00,4.90,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=139 FAILED [class=1, true class=2] features=(6.00,3.00,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx sample=143 FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90] Iris_AllClassifiers (EURUSD,H1) 22 model:IRIS_models\categorical_naive_bayes_classifier_iris.onnx accuracy: 0.9333 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=51 FAILED [class=2, true class=1] features=(7.00,3.20,4.70,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=52 FAILED [class=2, true class=1] features=(6.40,3.20,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=53 FAILED [class=2, true class=1] features=(6.90,3.10,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=57 FAILED [class=2, true class=1] features=(6.30,3.30,4.70,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=62 FAILED [class=2, true class=1] features=(5.90,3.00,4.20,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=65 FAILED [class=2, true class=1] features=(5.60,2.90,3.60,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=66 FAILED [class=2, true class=1] features=(6.70,3.10,4.40,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=67 FAILED [class=2, true class=1] features=(5.60,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=76 FAILED [class=2, true class=1] features=(6.60,3.00,4.40,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=79 FAILED [class=2, true class=1] features=(6.00,2.90,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=86 FAILED [class=2, true class=1] features=(6.00,3.40,4.50,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=87 FAILED [class=2, true class=1] features=(6.70,3.10,4.70,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=89 FAILED [class=2, true class=1] features=(5.60,3.00,4.10,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=92 FAILED [class=2, true class=1] features=(6.10,3.00,4.60,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=109 FAILED [class=1, true class=2] features=(6.70,2.50,5.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifier_iris.onnx sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_AllClassifiers (EURUSD,H1) 23 model:IRIS_models\ridge_classifier_iris.onnx accuracy: 0.8533 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=51 FAILED [class=2, true class=1] features=(7.00,3.20,4.70,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=52 FAILED [class=2, true class=1] features=(6.40,3.20,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=53 FAILED [class=2, true class=1] features=(6.90,3.10,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=57 FAILED [class=2, true class=1] features=(6.30,3.30,4.70,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=62 FAILED [class=2, true class=1] features=(5.90,3.00,4.20,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=65 FAILED [class=2, true class=1] features=(5.60,2.90,3.60,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=66 FAILED [class=2, true class=1] features=(6.70,3.10,4.40,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=67 FAILED [class=2, true class=1] features=(5.60,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=76 FAILED [class=2, true class=1] features=(6.60,3.00,4.40,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=79 FAILED [class=2, true class=1] features=(6.00,2.90,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=86 FAILED [class=2, true class=1] features=(6.00,3.40,4.50,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=87 FAILED [class=2, true class=1] features=(6.70,3.10,4.70,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=89 FAILED [class=2, true class=1] features=(5.60,3.00,4.10,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=92 FAILED [class=2, true class=1] features=(6.10,3.00,4.60,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=109 FAILED [class=1, true class=2] features=(6.70,2.50,5.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\ridge_classifiercv_iris.onnx sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_AllClassifiers (EURUSD,H1) 24 model:IRIS_models\ridge_classifiercv_iris.onnx accuracy: 0.8533 Iris_AllClassifiers (EURUSD,H1) ONNX: Removing initializer 'class_log_prior'. It is not used by any node and should be removed from the model. Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=51 FAILED [class=2, true class=1] features=(7.00,3.20,4.70,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=52 FAILED [class=2, true class=1] features=(6.40,3.20,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=53 FAILED [class=2, true class=1] features=(6.90,3.10,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=54 FAILED [class=2, true class=1] features=(5.50,2.30,4.00,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=55 FAILED [class=2, true class=1] features=(6.50,2.80,4.60,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=56 FAILED [class=2, true class=1] features=(5.70,2.80,4.50,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=57 FAILED [class=2, true class=1] features=(6.30,3.30,4.70,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=58 FAILED [class=2, true class=1] features=(4.90,2.40,3.30,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=59 FAILED [class=2, true class=1] features=(6.60,2.90,4.60,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=60 FAILED [class=2, true class=1] features=(5.20,2.70,3.90,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=61 FAILED [class=2, true class=1] features=(5.00,2.00,3.50,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=62 FAILED [class=2, true class=1] features=(5.90,3.00,4.20,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=63 FAILED [class=2, true class=1] features=(6.00,2.20,4.00,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=64 FAILED [class=2, true class=1] features=(6.10,2.90,4.70,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=65 FAILED [class=2, true class=1] features=(5.60,2.90,3.60,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=66 FAILED [class=2, true class=1] features=(6.70,3.10,4.40,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=67 FAILED [class=2, true class=1] features=(5.60,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=68 FAILED [class=2, true class=1] features=(5.80,2.70,4.10,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=69 FAILED [class=2, true class=1] features=(6.20,2.20,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=70 FAILED [class=2, true class=1] features=(5.60,2.50,3.90,1.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=71 FAILED [class=2, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=72 FAILED [class=2, true class=1] features=(6.10,2.80,4.00,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=73 FAILED [class=2, true class=1] features=(6.30,2.50,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=74 FAILED [class=2, true class=1] features=(6.10,2.80,4.70,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=75 FAILED [class=2, true class=1] features=(6.40,2.90,4.30,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=76 FAILED [class=2, true class=1] features=(6.60,3.00,4.40,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=77 FAILED [class=2, true class=1] features=(6.80,2.80,4.80,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=78 FAILED [class=2, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=79 FAILED [class=2, true class=1] features=(6.00,2.90,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=80 FAILED [class=0, true class=1] features=(5.70,2.60,3.50,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=81 FAILED [class=2, true class=1] features=(5.50,2.40,3.80,1.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=82 FAILED [class=2, true class=1] features=(5.50,2.40,3.70,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=83 FAILED [class=2, true class=1] features=(5.80,2.70,3.90,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=84 FAILED [class=2, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=85 FAILED [class=2, true class=1] features=(5.40,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=86 FAILED [class=2, true class=1] features=(6.00,3.40,4.50,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=87 FAILED [class=2, true class=1] features=(6.70,3.10,4.70,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=88 FAILED [class=2, true class=1] features=(6.30,2.30,4.40,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=89 FAILED [class=2, true class=1] features=(5.60,3.00,4.10,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=90 FAILED [class=2, true class=1] features=(5.50,2.50,4.00,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=91 FAILED [class=2, true class=1] features=(5.50,2.60,4.40,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=92 FAILED [class=2, true class=1] features=(6.10,3.00,4.60,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=93 FAILED [class=2, true class=1] features=(5.80,2.60,4.00,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=94 FAILED [class=2, true class=1] features=(5.00,2.30,3.30,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=95 FAILED [class=2, true class=1] features=(5.60,2.70,4.20,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=96 FAILED [class=2, true class=1] features=(5.70,3.00,4.20,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=97 FAILED [class=2, true class=1] features=(5.70,2.90,4.20,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=98 FAILED [class=2, true class=1] features=(6.20,2.90,4.30,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=99 FAILED [class=0, true class=1] features=(5.10,2.50,3.00,1.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\complement_naive_bayes_classifier_iris.onnx sample=100 FAILED [class=2, true class=1] features=(5.70,2.80,4.10,1.30] Iris_AllClassifiers (EURUSD,H1) 25 model:IRIS_models\complement_naive_bayes_classifier_iris.onnx accuracy: 0.6667 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=2 FAILED [class=1, true class=0] features=(4.90,3.00,1.40,0.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=9 FAILED [class=1, true class=0] features=(4.40,2.90,1.40,0.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=10 FAILED [class=1, true class=0] features=(4.90,3.10,1.50,0.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=13 FAILED [class=1, true class=0] features=(4.80,3.00,1.40,0.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=21 FAILED [class=1, true class=0] features=(5.40,3.40,1.70,0.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=26 FAILED [class=1, true class=0] features=(5.00,3.00,1.60,0.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=31 FAILED [class=1, true class=0] features=(4.80,3.10,1.60,0.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=35 FAILED [class=1, true class=0] features=(4.90,3.10,1.50,0.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=42 FAILED [class=1, true class=0] features=(4.50,2.30,1.30,0.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=46 FAILED [class=1, true class=0] features=(4.80,3.00,1.40,0.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=102 FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=103 FAILED [class=1, true class=2] features=(7.10,3.00,5.90,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=104 FAILED [class=1, true class=2] features=(6.30,2.90,5.60,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=105 FAILED [class=1, true class=2] features=(6.50,3.00,5.80,2.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=106 FAILED [class=1, true class=2] features=(7.60,3.00,6.60,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=107 FAILED [class=1, true class=2] features=(4.90,2.50,4.50,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=108 FAILED [class=1, true class=2] features=(7.30,2.90,6.30,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=109 FAILED [class=1, true class=2] features=(6.70,2.50,5.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=110 FAILED [class=1, true class=2] features=(7.20,3.60,6.10,2.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=111 FAILED [class=1, true class=2] features=(6.50,3.20,5.10,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=112 FAILED [class=1, true class=2] features=(6.40,2.70,5.30,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=113 FAILED [class=1, true class=2] features=(6.80,3.00,5.50,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=114 FAILED [class=1, true class=2] features=(5.70,2.50,5.00,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=116 FAILED [class=1, true class=2] features=(6.40,3.20,5.30,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=117 FAILED [class=1, true class=2] features=(6.50,3.00,5.50,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=118 FAILED [class=1, true class=2] features=(7.70,3.80,6.70,2.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=119 FAILED [class=1, true class=2] features=(7.70,2.60,6.90,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=120 FAILED [class=1, true class=2] features=(6.00,2.20,5.00,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=121 FAILED [class=1, true class=2] features=(6.90,3.20,5.70,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=122 FAILED [class=1, true class=2] features=(5.60,2.80,4.90,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=123 FAILED [class=1, true class=2] features=(7.70,2.80,6.70,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=124 FAILED [class=1, true class=2] features=(6.30,2.70,4.90,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=125 FAILED [class=1, true class=2] features=(6.70,3.30,5.70,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=126 FAILED [class=1, true class=2] features=(7.20,3.20,6.00,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=127 FAILED [class=1, true class=2] features=(6.20,2.80,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=128 FAILED [class=1, true class=2] features=(6.10,3.00,4.90,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=129 FAILED [class=1, true class=2] features=(6.40,2.80,5.60,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=130 FAILED [class=1, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=131 FAILED [class=1, true class=2] features=(7.40,2.80,6.10,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=132 FAILED [class=1, true class=2] features=(7.90,3.80,6.40,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=133 FAILED [class=1, true class=2] features=(6.40,2.80,5.60,2.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=134 FAILED [class=1, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=135 FAILED [class=1, true class=2] features=(6.10,2.60,5.60,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=136 FAILED [class=1, true class=2] features=(7.70,3.00,6.10,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=137 FAILED [class=1, true class=2] features=(6.30,3.40,5.60,2.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=138 FAILED [class=1, true class=2] features=(6.40,3.10,5.50,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=139 FAILED [class=1, true class=2] features=(6.00,3.00,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=140 FAILED [class=1, true class=2] features=(6.90,3.10,5.40,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=141 FAILED [class=1, true class=2] features=(6.70,3.10,5.60,2.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=142 FAILED [class=1, true class=2] features=(6.90,3.10,5.10,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=143 FAILED [class=1, true class=2] features=(5.80,2.70,5.10,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=144 FAILED [class=1, true class=2] features=(6.80,3.20,5.90,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=145 FAILED [class=1, true class=2] features=(6.70,3.30,5.70,2.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=146 FAILED [class=1, true class=2] features=(6.70,3.00,5.20,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=147 FAILED [class=1, true class=2] features=(6.30,2.50,5.00,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=148 FAILED [class=1, true class=2] features=(6.50,3.00,5.20,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=149 FAILED [class=1, true class=2] features=(6.20,3.40,5.40,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\perceptron_classifier_iris.onnx sample=150 FAILED [class=1, true class=2] features=(5.90,3.00,5.10,1.80] Iris_AllClassifiers (EURUSD,H1) 26 model:IRIS_models\perceptron_classifier_iris.onnx accuracy: 0.6133 Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=51 FAILED [class=0, true class=1] features=(7.00,3.20,4.70,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=52 FAILED [class=0, true class=1] features=(6.40,3.20,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=53 FAILED [class=0, true class=1] features=(6.90,3.10,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=54 FAILED [class=0, true class=1] features=(5.50,2.30,4.00,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=55 FAILED [class=0, true class=1] features=(6.50,2.80,4.60,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=56 FAILED [class=0, true class=1] features=(5.70,2.80,4.50,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=57 FAILED [class=0, true class=1] features=(6.30,3.30,4.70,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=58 FAILED [class=0, true class=1] features=(4.90,2.40,3.30,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=59 FAILED [class=0, true class=1] features=(6.60,2.90,4.60,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=60 FAILED [class=0, true class=1] features=(5.20,2.70,3.90,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=61 FAILED [class=0, true class=1] features=(5.00,2.00,3.50,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=62 FAILED [class=0, true class=1] features=(5.90,3.00,4.20,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=63 FAILED [class=0, true class=1] features=(6.00,2.20,4.00,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=64 FAILED [class=0, true class=1] features=(6.10,2.90,4.70,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=65 FAILED [class=0, true class=1] features=(5.60,2.90,3.60,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=66 FAILED [class=0, true class=1] features=(6.70,3.10,4.40,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=67 FAILED [class=0, true class=1] features=(5.60,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=68 FAILED [class=0, true class=1] features=(5.80,2.70,4.10,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=69 FAILED [class=0, true class=1] features=(6.20,2.20,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=70 FAILED [class=0, true class=1] features=(5.60,2.50,3.90,1.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=71 FAILED [class=0, true class=1] features=(5.90,3.20,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=72 FAILED [class=0, true class=1] features=(6.10,2.80,4.00,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=73 FAILED [class=0, true class=1] features=(6.30,2.50,4.90,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=74 FAILED [class=0, true class=1] features=(6.10,2.80,4.70,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=75 FAILED [class=0, true class=1] features=(6.40,2.90,4.30,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=76 FAILED [class=0, true class=1] features=(6.60,3.00,4.40,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=77 FAILED [class=0, true class=1] features=(6.80,2.80,4.80,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=78 FAILED [class=0, true class=1] features=(6.70,3.00,5.00,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=79 FAILED [class=0, true class=1] features=(6.00,2.90,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=80 FAILED [class=0, true class=1] features=(5.70,2.60,3.50,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=81 FAILED [class=0, true class=1] features=(5.50,2.40,3.80,1.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=82 FAILED [class=0, true class=1] features=(5.50,2.40,3.70,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=83 FAILED [class=0, true class=1] features=(5.80,2.70,3.90,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=84 FAILED [class=0, true class=1] features=(6.00,2.70,5.10,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=85 FAILED [class=0, true class=1] features=(5.40,3.00,4.50,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=86 FAILED [class=0, true class=1] features=(6.00,3.40,4.50,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=87 FAILED [class=0, true class=1] features=(6.70,3.10,4.70,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=88 FAILED [class=0, true class=1] features=(6.30,2.30,4.40,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=89 FAILED [class=0, true class=1] features=(5.60,3.00,4.10,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=90 FAILED [class=0, true class=1] features=(5.50,2.50,4.00,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=91 FAILED [class=0, true class=1] features=(5.50,2.60,4.40,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=92 FAILED [class=0, true class=1] features=(6.10,3.00,4.60,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=93 FAILED [class=0, true class=1] features=(5.80,2.60,4.00,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=94 FAILED [class=0, true class=1] features=(5.00,2.30,3.30,1.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=95 FAILED [class=0, true class=1] features=(5.60,2.70,4.20,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=96 FAILED [class=0, true class=1] features=(5.70,3.00,4.20,1.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=97 FAILED [class=0, true class=1] features=(5.70,2.90,4.20,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=98 FAILED [class=0, true class=1] features=(6.20,2.90,4.30,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=99 FAILED [class=0, true class=1] features=(5.10,2.50,3.00,1.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=100 FAILED [class=0, true class=1] features=(5.70,2.80,4.10,1.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=101 FAILED [class=0, true class=2] features=(6.30,3.30,6.00,2.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=102 FAILED [class=0, true class=2] features=(5.80,2.70,5.10,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=103 FAILED [class=0, true class=2] features=(7.10,3.00,5.90,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=104 FAILED [class=0, true class=2] features=(6.30,2.90,5.60,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=105 FAILED [class=0, true class=2] features=(6.50,3.00,5.80,2.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=106 FAILED [class=0, true class=2] features=(7.60,3.00,6.60,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=107 FAILED [class=0, true class=2] features=(4.90,2.50,4.50,1.70] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=108 FAILED [class=0, true class=2] features=(7.30,2.90,6.30,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=109 FAILED [class=0, true class=2] features=(6.70,2.50,5.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=110 FAILED [class=0, true class=2] features=(7.20,3.60,6.10,2.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=111 FAILED [class=0, true class=2] features=(6.50,3.20,5.10,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=112 FAILED [class=0, true class=2] features=(6.40,2.70,5.30,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=113 FAILED [class=0, true class=2] features=(6.80,3.00,5.50,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=114 FAILED [class=0, true class=2] features=(5.70,2.50,5.00,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=115 FAILED [class=0, true class=2] features=(5.80,2.80,5.10,2.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=116 FAILED [class=0, true class=2] features=(6.40,3.20,5.30,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=117 FAILED [class=0, true class=2] features=(6.50,3.00,5.50,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=118 FAILED [class=0, true class=2] features=(7.70,3.80,6.70,2.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=119 FAILED [class=0, true class=2] features=(7.70,2.60,6.90,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=120 FAILED [class=0, true class=2] features=(6.00,2.20,5.00,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=121 FAILED [class=0, true class=2] features=(6.90,3.20,5.70,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=122 FAILED [class=0, true class=2] features=(5.60,2.80,4.90,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=123 FAILED [class=0, true class=2] features=(7.70,2.80,6.70,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=124 FAILED [class=0, true class=2] features=(6.30,2.70,4.90,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=125 FAILED [class=0, true class=2] features=(6.70,3.30,5.70,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=126 FAILED [class=0, true class=2] features=(7.20,3.20,6.00,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=127 FAILED [class=0, true class=2] features=(6.20,2.80,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=128 FAILED [class=0, true class=2] features=(6.10,3.00,4.90,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=129 FAILED [class=0, true class=2] features=(6.40,2.80,5.60,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=130 FAILED [class=0, true class=2] features=(7.20,3.00,5.80,1.60] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=131 FAILED [class=0, true class=2] features=(7.40,2.80,6.10,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=132 FAILED [class=0, true class=2] features=(7.90,3.80,6.40,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=133 FAILED [class=0, true class=2] features=(6.40,2.80,5.60,2.20] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=134 FAILED [class=0, true class=2] features=(6.30,2.80,5.10,1.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=135 FAILED [class=0, true class=2] features=(6.10,2.60,5.60,1.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=136 FAILED [class=0, true class=2] features=(7.70,3.00,6.10,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=137 FAILED [class=0, true class=2] features=(6.30,3.40,5.60,2.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=138 FAILED [class=0, true class=2] features=(6.40,3.10,5.50,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=139 FAILED [class=0, true class=2] features=(6.00,3.00,4.80,1.80] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=140 FAILED [class=0, true class=2] features=(6.90,3.10,5.40,2.10] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=141 FAILED [class=0, true class=2] features=(6.70,3.10,5.60,2.40] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=142 FAILED [class=0, true class=2] features=(6.90,3.10,5.10,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=143 FAILED [class=0, true class=2] features=(5.80,2.70,5.10,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=144 FAILED [class=0, true class=2] features=(6.80,3.20,5.90,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=145 FAILED [class=0, true class=2] features=(6.70,3.30,5.70,2.50] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=146 FAILED [class=0, true class=2] features=(6.70,3.00,5.20,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=147 FAILED [class=0, true class=2] features=(6.30,2.50,5.00,1.90] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=148 FAILED [class=0, true class=2] features=(6.50,3.00,5.20,2.00] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=149 FAILED [class=0, true class=2] features=(6.20,3.40,5.40,2.30] Iris_AllClassifiers (EURUSD,H1) model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx sample=150 FAILED [class=0, true class=2] features=(5.90,3.00,5.10,1.80] Iris_AllClassifiers (EURUSD,H1) 27 model:IRIS_models\bernoulli_naive_bayes_classifier_iris.onnx accuracy: 0.3333
2.29. ONNX'e dönüştürülemeyen Scikit-learn sınıflandırma modelleri
Bazı sınıflandırma modelleri convert_sklearn işlemindeki hatalar nedeniyle ONNX formatına dönüştürülemedi.
2.29.1. DummyClassifier
DummyClassifier, Scikit-learn kütüphanesinde sınıflandırma görevleri için basit bir temel model olarak kullanılan bir sınıflandırıcıdır. Daha karmaşık sınıflandırma modellerinin performansını test etmek ve değerlendirmek için tasarlanmıştır.
Çalışma prensibi:
DummyClassifier çok basit bir şekilde çalışır; girdi verilerini dikkate almadan rastgele veya saf tahminler yapar. Farklı stratejiler sunar ("strategy" parametresi aracılığıyla seçilir):
- "most_frequent" (En sık sınıf): Bu strateji her zaman eğitim veri kümesinde en sık görünen sınıfı tahmin eder. Sınıfların dengesiz olduğu ve baskın sınıfı tahmin etmeniz gereken durumlarda yararlı olabilir.
- "stratified" (Katmanlı seçim): Bu strateji, eğitim veri kümesindeki sınıf dağılımına uyan tahminler yapmaya çalışır. Rastgele tahmin kullanır ancak sınıf oranlarını dikkate alır.
- "uniform" (Tekdüze dağılım): Bu strateji, her sınıf için eşit olasılıkla rastgele tahminler yapar. Sınıflar dengeli olduğunda ve modelinizin ortalama olarak nasıl performans gösterdiğini test etmek istediğinizde kullanışlıdır.
Avantajlar:
- Basitlik: DummyClassifier, temel bir modeli ne kadar hızlı eğitebileceğinizi ve hangi sonuçları ürettiğini test etmek için kullanışlıdır. Diğer sınıflandırıcıların hızlı bir performans değerlendirmesi için yararlı olabilir.
- Veri hattı (pipeline) kullanımı: DummyClassifier'ı bir veri hattı (pipeline) içinde temel model olarak kullanabilir, karşılaştırma ve test için diğer dönüşümler ve modellerle birleştirebilirsiniz.
Sınırlamalar:
- Verileri dikkate almaz: DummyClassifier, gerçek verileri dikkate almadan rastgele veya saf tahminler yapar. Verilerden öğrenemez veya kalıpları keşfedemez.
- Karmaşık görevler için uygun değildir: Bu sınıflandırıcı, karmaşık sınıflandırma görevlerini çözmek için tasarlanmamıştır ve genellikle büyük veri kümeleri ve karmaşık kalıplar içeren görevler için iyi sonuçlar vermez.
- Bilgilendirme eksikliği: DummyClassifier kullanılarak elde edilen sonuçlar bilgilendirici olmayabilir ve model performansı hakkında yararlı bilgiler sağlamayabilir. Kod testi ve değerlendirmesi için daha kullanışlıdırlar.
DummyClassifier, sınıflandırma modellerini ilk kez test etmek ve değerlendirmek için kullanışlı bir araçtır, ancak karmaşık görevlerde kullanımı sınırlıdır ve daha gelişmiş sınıflandırma algoritmalarının yerini alamaz.
2.29.1.1. DummyClassifier modelini oluşturmak için kod
# Iris_DummyClassifier.py
# The code demonstrates the process of training DummyClassifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model.
# It also evaluates the accuracy of both the original model and the ONNX model.
# Copyright 2023, MetaQuotes Ltd.
# https://www.mql5.com
# import necessary libraries
from sklearn import datasets
from sklearn.dummy import DummyClassifier
from sklearn.metrics import accuracy_score, classification_report
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import onnxruntime as ort
import numpy as np
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 a DummyClassifier model with the strategy "most_frequent"
dummy_classifier = DummyClassifier(strategy="most_frequent")
# train the model on the entire dataset
dummy_classifier.fit(X, y)
# predict classes for the entire dataset
y_pred = dummy_classifier.predict(X)
# evaluate the model's accuracy
accuracy = accuracy_score(y, y_pred)
print("Accuracy of DummyClassifier model:", accuracy)
# display the classification report
print("\nClassification Report:\n", classification_report(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(dummy_classifier, initial_types=initial_type, target_opset=12)
# save the model to a file
onnx_filename = data_path + "dummy_classifier_iris.onnx"
with open(onnx_filename, "wb") as f:
f.write(onnx_model.SerializeToString())
# print model path
print(f"Model saved to {onnx_filename}")
# 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
# display information about input tensors in ONNX
print("\nInformation about input tensors in ONNX:")
for i, input_tensor in enumerate(onnx_session.get_inputs()):
print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}")
# display information about output tensors in ONNX
print("\nInformation about output tensors in ONNX:")
for i, output_tensor in enumerate(onnx_session.get_outputs()):
print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}")
# 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)
print("\nAccuracy of DummyClassifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 0.33 1.00 0.50 50
Python 1 0.00 0.00 0.00 50
Python 2 0.00 0.00 0.00 50
Python
Python accuracy 0.33 150
Python macro avg 0.11 0.33 0.17 150
Python weighted avg 0.11 0.33 0.17 150
Python
Model Scikit-learn'de başarıyla oluşturuldu ve çalıştırıldı, ancak ONNX'e dönüştürme sırasında hatalar oluştu.
"Errors" sekmesinde, ONNX formatına dönüştürme hatalarına ilişkin mesajlar görüntülenir:
onnx_model = convert_topology( convert.py 208 1
topology.convert_operators(container=container, verbose=verbose) _topology.py 1532 1
self.call_shape_calculator(operator) _topology.py 1348 1
operator.infer_types() _topology.py 1163 1
raise MissingShapeCalculator( _topology.py 629 1
skl2onnx.common.exceptions.MissingShapeCalculator: Unable to find a shape calculator for type '<class 'sklearn.dummy.DummyClassifier'>'. _topology.py 629 1
It usually means the pipeline being converted contains a _topology.py 629 1
transformer or a predictor with no corresponding converter _topology.py 629 1
implemented in sklearn-onnx. If the converted is implemented _topology.py 629 1
in another library, you need to register _topology.py 629 1
the converted so that it can be used by sklearn-onnx (function _topology.py 629 1
update_registered_converter). If the model is not yet covered _topology.py 629 1
by sklearn-onnx, you may raise an issue to _topology.py 629 1
https://github.com/onnx/sklearn-onnx/issues _topology.py 629 1
to get the converter implemented or even contribute to the _topology.py 629 1
project. If the model is a custom model, a new converter must _topology.py 629 1
be implemented. Examples can be found in the gallery. _topology.py 629 1
Iris_DummyClassifier.py finished in 2071 ms 19 1
Bu nedenle, DummyClassifier modeli ONNX'e dönüştürülememiştir.
2.29.2. GaussianProcessClassifier
GaussianProcessClassifier, sınıflandırma görevleri için Gauss süreçlerini kullanan bir sınıflandırıcıdır. Gauss süreçlerini kullanan modeller ailesine aittir ve olasılıksal sınıf hesaplamalarının gerekli olduğu görevlerde yararlı olabilir.
Çalışma prensibi:
- GaussianProcessClassifier, özellik uzayından sınıf olasılık hesaplamaları uzayına eşlemeyi modellemek için bir Gauss süreci kullanır.
- Bir noktanın her bir sınıfa ait olma olasılığını değerlendirerek her bir sınıf için olasılıksal bir model oluşturur.
- Sınıflandırma sırasında, belirli bir nokta için en yüksek olasılığa sahip sınıfı seçer.
Avantajlar:
- Olasılıksal sınıflandırma: GaussianProcessClassifier, model belirsizliğini değerlendirmek için yararlı olabilecek olasılıksal sınıf hesaplamaları sağlar.
- Uyarlanabilirlik: Bu sınıflandırıcı verilere uyum sağlayabilir ve yeni gözlemlere dayanarak tahminlerini güncelleyebilir.
- Kalibrasyon: Model, olasılık hesaplamalarını iyileştirmek için "calibrate" yöntemi kullanılarak kalibre edilebilir.
Sınırlamalar:
- Hesaplama karmaşıklığı: GaussianProcessClassifier büyük veri kümeleri ve/veya yüksek boyutlu özellik uzayları için hesaplama açısından maliyetli olabilir.
- Büyük örneklemler için uygun değildir: Hesaplama karmaşıklığı nedeniyle, bu sınıflandırıcı büyük veri kümeleri üzerinde eğitim için verimli olmayabilir.
- Yorumlama karmaşıklığı: Gauss süreçlerinin yorumlanması ve anlaşılması, özellikle Bayes istatistikleri konusunda deneyimi olmayan kullanıcılar için zor olabilir.
GaussianProcessClassifier, olasılıksal sınıf hesaplamalarının önemli olduğu ve hesaplama maliyetlerinin üstesinden gelinebilen görevlerde değerlidir. Aksi takdirde, büyük veri kümelerinde veya basit veri yapılarında sınıflandırma görevleri için diğer sınıflandırma algoritmaları daha uygun olabilir.
2.29.2.1. GaussianProcessClassifier modelini oluşturmak için kod# Iris_GaussianProcessClassifier.py
# The code demonstrates the process of training Iris_GaussianProcess Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model.
# It also evaluates the accuracy of both the original model and the ONNX model.
# Copyright 2023, MetaQuotes Ltd.
# https://www.mql5.com
# import necessary libraries
from sklearn import datasets
from sklearn.gaussian_process import GaussianProcessClassifier
from sklearn.gaussian_process.kernels import RBF
from sklearn.metrics import accuracy_score, classification_report
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import onnxruntime as ort
import numpy as np
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 a GaussianProcessClassifier model with an RBF kernel
kernel = 1.0 * RBF(1.0)
gpc_model = GaussianProcessClassifier(kernel=kernel)
# train the model on the entire dataset
gpc_model.fit(X, y)
# predict classes for the entire dataset
y_pred = gpc_model.predict(X)
# evaluate the model's accuracy
accuracy = accuracy_score(y, y_pred)
print("Accuracy of GaussianProcessClassifier model:", accuracy)
# display the classification report
print("\nClassification Report:\n", classification_report(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(gpc_model, initial_types=initial_type, target_opset=12)
# save the model to a file
onnx_filename = data_path + "gpc_iris.onnx"
with open(onnx_filename, "wb") as f:
f.write(onnx_model.SerializeToString())
# print the path to the model
print(f"Model saved to {onnx_filename}")
# 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
# display information about input tensors in ONNX
print("\nInformation about input tensors in ONNX:")
for i, input_tensor in enumerate(onnx_session.get_inputs()):
print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}")
# display information about output tensors in ONNX
print("\nInformation about output tensors in ONNX:")
for i, output_tensor in enumerate(onnx_session.get_outputs()):
print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}")
# 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)
print("\nAccuracy of GaussianProcessClassifier model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.98 0.98 0.98 50
Python 2 0.98 0.98 0.98 50
Python
Python accuracy 0.99 150
Python macro avg 0.99 0.99 0.99 150
Python weighted avg 0.99 0.99 0.99 150
Python
"Errors" sekmesinde, ONNX formatına dönüştürme hatalarına ilişkin mesajlar görüntülenir:
onnx_model = convert_topology( convert.py 208 1
topology.convert_operators(container=container, verbose=verbose) _topology.py 1532 1
self.call_converter(operator, container, verbose=verbose) _topology.py 1349 1
conv(self.scopes[0], operator, container) _topology.py 1132 1
return self._fct(*args) _registration.py 27 1
raise NotImplementedError("Only binary classification is iplemented.") gaussian_process.py 247 1
NotImplementedError: Only binary classification is iplemented. gaussian_process.py 247 1
Iris_GaussianProcessClassifier.py finished in 4004 ms 9 1
Bu nedenle, GaussianProcessClassifier modeli ONNX'e dönüştürülememiştir.
2.29.3. LabelPropagation Classifier
LabelPropagation, sınıflandırma görevleri için kullanılan yarı denetimli bir öğrenme yöntemidir. Bu yöntemin arkasındaki temel fikir, etiketleri (sınıfları) etiketli örneklerden etiketsiz örneklere grafik tabanlı bir veri yapısında yaymaktır.
LabelPropagation süreci:
- Düğümlerin veri örneklerini temsil ettiği ve düğümler arasındaki kenarların örnekler arasındaki benzerliği veya yakınlığı yansıttığı bir grafiğin oluşturulmasıyla başlar.
- İlk etiket ataması: Etiketli örneklere etiketleri verilir ve etiketsiz örnekler tanımlanmamış bir etiketle başlar.
- Grafik üzerinde etiket yayılımı: Etiketli örneklerden gelen etiketler, örnekler arasındaki benzerliğe dayalı olarak etiketsiz örneklere yayılır. Bu benzerlik çeşitli şekillerde belirlenebilir, örneğin grafikteki en yakın komşular kullanılarak.
- Yinelemeli süreç: Etiketler birkaç yinelemede değişebilir ve her yinelemede mevcut etiketlere ve örnek benzerliğine göre etiketsiz örneklerin etiketleri güncellenir.
- Stabilizasyon: Süreç, etiketler stabilleşene veya belirli bir durma kriteri karşılanana kadar devam eder.
LabelPropagation'ın avantajları:
- Etiketsiz verilerden gelen bilgileri kullanır: LabelPropagation, sınıflandırma kalitesini artırmak için etiketsiz örneklerden gelen bilgilerin kullanılmasına olanak tanır. Bu, özellikle etiketli verilerin az olduğu durumlarda kullanışlıdır.
- Gürültüye karşı dayanıklılık: Yöntem, örnek benzerliğini hesaba kattığı ve yalnızca etiketlere dayanmadığı için gürültülü verileri etkili bir şekilde yönetir.
LabelPropagation'ın sınırlamaları:
- Grafik seçimine bağımlılık: LabelPropagation sınıflandırmasının kalitesi büyük ölçüde grafiğin seçimine ve örnek benzerliğini belirleme yöntemine bağlı olabilir. Yanlış parametre seçimleri kötü sonuçlara yol açabilir.
- Hesaplama karmaşıklığı: Verilerin büyüklüğü ve karmaşıklığının yanı sıra yöntem parametrelerine bağlı olarak, LabelPropagation önemli hesaplama kaynakları gerektirebilir.
- Aşırı uyum potansiyeli: Grafik çok fazla gürültülü kenar veya yanlış etiket içeriyorsa, yöntem aşırı uyum sağlayabilir.
- Yakınsama garanti edilmez: Nadir durumlarda, LabelPropagation stabil etiketlere yakınsamayabilir, bu da yineleme sayısının sınırlandırılmasını veya diğer ayarların yapılmasını gerektirir.
LabelPropagation güçlü bir yöntemdir, ancak iyi sonuçlar elde etmek için dikkatli parametre ayarlaması ve verilerin grafik yapısının analizini gerektirir.
2.29.3.1. LabelPropagation Classifier modelini oluşturmak için kod
# The code demonstrates the process of training LabelPropagation Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model.
# It also evaluates the accuracy of both the original model and the ONNX model.
# Copyright 2023, MetaQuotes Ltd.
# https://www.mql5.com
# import necessary libraries
from sklearn import datasets
from sklearn.semi_supervised import LabelPropagation
from sklearn.metrics import accuracy_score, classification_report
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import onnxruntime as ort
import numpy as np
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 a LabelPropagation model
lp_model = LabelPropagation()
# train the model on the entire dataset
lp_model.fit(X, y)
# predict classes for the entire dataset
y_pred = lp_model.predict(X)
# evaluate the model's accuracy
accuracy = accuracy_score(y, y_pred)
print("Accuracy of LabelPropagation model:", accuracy)
# display the classification report
print("\nClassification Report:\n", classification_report(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(lp_model, initial_types=initial_type, target_opset=12)
# save the model to a file
onnx_filename = data_path + "lp_iris.onnx"
with open(onnx_filename, "wb") as f:
f.write(onnx_model.SerializeToString())
# print the path to the model
print(f"Model saved to {onnx_filename}")
# 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
# display information about input tensors in ONNX
print("\nInformation about input tensors in ONNX:")
for i, input_tensor in enumerate(onnx_session.get_inputs()):
print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}")
# display information about output tensors in ONNX
print("\nInformation about output tensors in ONNX:")
for i, output_tensor in enumerate(onnx_session.get_outputs()):
print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}")
# 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)
print("\nAccuracy of LabelPropagation model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 1.00 1.00 50
Python 2 1.00 1.00 1.00 50
Python
Python accuracy 1.00 150
Python macro avg 1.00 1.00 1.00 150
Python weighted avg 1.00 1.00 1.00 150
Python
Model oluşturuldu, ancak ONNX formatına dönüştürme sırasında hatalar meydana geldi.
"Errors" sekmesinde, ONNX formatına dönüştürme hatalarına ilişkin mesajlar görüntülenir:
onnx_model = convert_topology( convert.py 208 1
topology.convert_operators(container=container, verbose=verbose) _topology.py 1532 1
self.call_shape_calculator(operator) _topology.py 1348 1
operator.infer_types() _topology.py 1163 1
raise MissingShapeCalculator( _topology.py 629 1
skl2onnx.common.exceptions.MissingShapeCalculator: Unable to find a shape calculator for type '<class 'sklearn.semi_supervised._label_propagation.LabelPropagation'>'. _topology.py 629 1
It usually means the pipeline being converted contains a _topology.py 629 1
transformer or a predictor with no corresponding converter _topology.py 629 1
implemented in sklearn-onnx. If the converted is implemented _topology.py 629 1
in another library, you need to register _topology.py 629 1
the converted so that it can be used by sklearn-onnx (function _topology.py 629 1
update_registered_converter). If the model is not yet covered _topology.py 629 1
by sklearn-onnx, you may raise an issue to _topology.py 629 1
https://github.com/onnx/sklearn-onnx/issues _topology.py 629 1
to get the converter implemented or even contribute to the _topology.py 629 1
project. If the model is a custom model, a new converter must _topology.py 629 1
be implemented. Examples can be found in the gallery. _topology.py 629 1
Iris_LabelPropagation.py finished in 2064 ms 19 1
2.29.4. LabelSpreading Classifier
LabelSpreading, sınıflandırma görevleri için kullanılan yarı denetimli bir öğrenme yöntemidir. LabelPropagation'a benzer şekilde, etiketlerin (sınıfların) etiketli örneklerden etiketsiz örneklere grafik tabanlı bir veri yapısında yayılması fikrine dayanır. Ancak LabelSpreading, etiket yayma işleminin ek stabilizasyonunu ve düzenlileştirmesini içerir.
LabelSpreading süreci:
- Düğümlerin veri örneklerini temsil ettiği ve düğümler arasındaki kenarların örnekler arasındaki benzerliği veya yakınlığı yansıttığı bir grafiğin oluşturulmasıyla başlar.
- İlk etiket ataması: Etiketli örneklere etiketleri verilir ve etiketsiz örnekler tanımlanmamış bir etiketle başlar.
- Grafik üzerinde etiket yayılımı: Etiketli örneklerden gelen etiketler, örnekler arasındaki benzerliğe dayalı olarak etiketsiz örneklere yayılır.
- Düzenlileştirme ve stabilizasyon: LabelSpreading, etiket yayma işlemini stabilize etmeye ve aşırı uyumu azaltmaya yardımcı olan düzenlileştirme özelliğini içerir. Bu, yalnızca örnekler arasındaki benzerliği değil, aynı zamanda komşu örneklerin etiketleri arasındaki farkları da dikkate alarak elde edilir.
- Yinelemeli süreç: Etiketler birkaç yineleme boyunca değişebilir; her yineleme, mevcut etiketlere ve düzenlileştirmeye dayalı olarak etiketsiz örneklerin etiketlerini günceller.
- Stabilizasyon: Süreç, etiketler stabilleşene veya belirli bir durma kriteri karşılanana kadar devam eder.
LabelSpreading'in avantajları:
- Etiketsiz verilerden gelen bilgileri kullanır: LabelSpreading, sınıflandırma kalitesini artırmak için etiketsiz örneklerden gelen bilgilerin kullanılmasına olanak tanır.
- Düzenlileştirme: LabelSpreading'de düzenlileştirmenin varlığı aşırı uyumu azaltmaya yardımcı olur ve etiket yayma sürecini daha kararlı hale getirir.
LabelSpreading'in sınırlamaları:
- Grafik seçimine bağımlılık: LabelPropagation'a benzer şekilde, LabelSpreading sınıflandırmasının kalitesi büyük ölçüde grafik ve yöntem parametrelerinin seçimine bağlı olabilir.
- Hesaplama karmaşıklığı: Verilerin büyüklüğü ve karmaşıklığının yanı sıra yöntem parametrelerine bağlı olarak, LabelSpreading önemli hesaplama kaynakları gerektirebilir.
- Her zaman yakınsamaz: Nadir durumlarda, LabelSpreading kararlı etiketlere yakınsamayabilir, bu da yineleme sayısının sınırlandırılmasını veya diğer ayarların yapılmasını gerektirir.
LabelSpreading de dikkatli ayarlama gerektiren bir yöntemdir ve sınıflandırma görevlerinde etiketsiz verileri kullanmak için güçlü bir araç olabilir.
2.29.4.1. LabelSpreading Classifier modelini oluşturmak için kod
# Iris_LabelSpreadingClassifier.py
# The code demonstrates the process of training LabelSpreading Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model.
# It also evaluates the accuracy of both the original model and the ONNX model.
# Copyright 2023, MetaQuotes Ltd.
# import necessary libraries
from sklearn import datasets
from sklearn.semi_supervised import LabelSpreading
from sklearn.metrics import accuracy_score, classification_report
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import onnxruntime as ort
import numpy as np
import sys
# get the script path
script_path = sys.argv[0]
last_index = script_path.rfind("\\") + 1
data_path = script_path[0:last_index]
# load the Iris dataset
iris = datasets.load_iris()
X = iris.data
y = iris.target
# create a LabelSpreading model
ls_model = LabelSpreading()
# train the model on the entire dataset
ls_model.fit(X, y)
# predict classes for the entire dataset
y_pred = ls_model.predict(X)
# evaluate the model's accuracy
accuracy = accuracy_score(y, y_pred)
print("Accuracy of LabelSpreading model:", accuracy)
# display the classification report
print("\nClassification Report:\n", classification_report(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(ls_model, initial_types=initial_type, target_opset=12)
# save the model to a file
onnx_filename = data_path + "ls_iris.onnx"
with open(onnx_filename, "wb") as f:
f.write(onnx_model.SerializeToString())
# print the path to the model
print(f"Model saved to {onnx_filename}")
# 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
# display information about input tensors in ONNX
print("\nInformation about input tensors in ONNX:")
for i, input_tensor in enumerate(onnx_session.get_inputs()):
print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}")
# display information about output tensors in ONNX
print("\nInformation about output tensors in ONNX:")
for i, output_tensor in enumerate(onnx_session.get_outputs()):
print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}")
# 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)
print("\nAccuracy of LabelSpreading model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 1.00 1.00 1.00 50
Python 2 1.00 1.00 1.00 50
Python
Python accuracy 1.00 150
Python macro avg 1.00 1.00 1.00 150
Python weighted avg 1.00 1.00 1.00 150
Python
"Errors" sekmesinde, ONNX formatına dönüştürme hatalarına ilişkin mesajlar görüntülenir:
onnx_model = convert_topology( convert.py 208 1
topology.convert_operators(container=container, verbose=verbose) _topology.py 1532 1
self.call_shape_calculator(operator) _topology.py 1348 1
operator.infer_types() _topology.py 1163 1
raise MissingShapeCalculator( _topology.py 629 1
skl2onnx.common.exceptions.MissingShapeCalculator: Unable to find a shape calculator for type '<class 'sklearn.semi_supervised._label_propagation.LabelSpreading'>'. _topology.py 629 1
It usually means the pipeline being converted contains a _topology.py 629 1
transformer or a predictor with no corresponding converter _topology.py 629 1
implemented in sklearn-onnx. If the converted is implemented _topology.py 629 1
in another library, you need to register _topology.py 629 1
the converted so that it can be used by sklearn-onnx (function _topology.py 629 1
update_registered_converter). If the model is not yet covered _topology.py 629 1
by sklearn-onnx, you may raise an issue to _topology.py 629 1
https://github.com/onnx/sklearn-onnx/issues _topology.py 629 1
to get the converter implemented or even contribute to the _topology.py 629 1
project. If the model is a custom model, a new converter must _topology.py 629 1
be implemented. Examples can be found in the gallery. _topology.py 629 1
Iris_LabelSpreading.py finished in 2032 ms 19 1
LabelSpreading Classifier modeli ONNX'e dönüştürülemedi.
2.29.5. NearestCentroid Classifier
NearestCentroid, her sınıf için bir merkez belirleme ve nesneleri en yakın merkeze göre sınıflandırma fikrine dayanan bir sınıflandırma yöntemidir. Bu yöntem çok sınıflı problemler için uygundur ve doğrusal olarak ayrılabilir sınıflara sahip veri kümelerinde iyi çalışır.
NearestCentroid süreci:
- Her sınıf için, o sınıfa ait tüm nesneler için özelliklerin ortalama değerini temsil eden bir merkez hesaplanır. Bu, söz konusu sınıftaki nesneler için her bir özelliğin ortalama değeri hesaplanarak yapılabilir.
- Yeni bir nesne sınıflandırılırken, tüm sınıfların merkezleri arasından en yakın merkezi hesaplanır.
- Yeni nesne, metrik uzayda merkezi kendisine en yakın olan sınıfa atanır.
NearestCentroid'in avantajları:
- Basitlik ve hız: NearestCentroid hesaplama açısından basit bir yöntemdir ve büyük veri kümeleri üzerinde hızlı bir şekilde çalışır.
- Doğrusal olarak ayrılabilen sınıflar için uygundur: Yöntem, sınıfların doğrusal olarak ayrılabildiği veya doğrusal olarak ayrılmaya yakın olduğu görevlerde iyi performans gösterir.
- Çok sınıflı problemler için etkilidir: NearestCentroid çok sınıflı problemler için uygundur ve topluluklarda temel sınıflandırıcı olarak kullanılabilir.
NearestCentroid'in sınırlamaları:
- Aykırı değerlere hassasiyet: NearestCentroid yöntemi, verilerdeki aykırı değerlere karşı hassastır, çünkü merkez aykırı değerlerin varlığıyla önemli ölçüde bozulabilir.
- Uzamsal yanlılık: Verilerdeki sınıflar farklı varyanslara ve şekillere sahipse, NearestCentroid yöntemi daha az verimli çalışabilir.
- Eşit ortalama olduğunu varsayar: Yöntem, sınıfların kabaca eşit özellik ortalamasına sahip olduğunu varsayar, ancak bu gerçek dünya verilerinde her zaman geçerli olmayabilir.
- Doğrusal olmayan görevler için uygun değildir: NearestCentroid, sınıflar arasında doğrusal olmayan sınırların olduğu görevler için uygun değildir.
NearestCentroid, özellikle sınıfların doğrusal olarak ayrılabilir olduğu ve verilerde aykırı değerlerin bulunmadığı belirli senaryolarda faydalı olabilecek basit ve yorumlanabilir bir sınıflandırma yöntemidir.
2.29.5.1. NearestCentroid Classifier modelini oluşturmak için kod
# Iris_NearestCentroidClassifier.py
# The code demonstrates the process of training NearestCentroid Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model.
# It also evaluates the accuracy of both the original model and the ONNX model.
# Copyright 2023, MetaQuotes Ltd.
# https://www.mql5.com
# import necessary libraries
from sklearn import datasets
from sklearn.neighbors import NearestCentroid
from sklearn.metrics import accuracy_score, classification_report
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import onnxruntime as ort
import numpy as np
import sys
# get the script path
script_path = sys.argv[0]
last_index = script_path.rfind("\\") + 1
data_path = script_path[0:last_index]
# load the Iris dataset
iris = datasets.load_iris()
X = iris.data
y = iris.target
# create a NearestCentroid model
nc_model = NearestCentroid()
# train the model on the entire dataset
nc_model.fit(X, y)
# predict classes for the entire dataset
y_pred = nc_model.predict(X)
# evaluate the model's accuracy
accuracy = accuracy_score(y, y_pred)
print("Accuracy of NearestCentroid model:", accuracy)
# display the classification report
print("\nClassification Report:\n", classification_report(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(nc_model, initial_types=initial_type, target_opset=12)
# save the model to a file
onnx_filename = data_path + "nc_iris.onnx"
with open(onnx_filename, "wb") as f:
f.write(onnx_model.SerializeToString())
# print the path to the model
print(f"Model saved to {onnx_filename}")
# 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
# display information about input tensors in ONNX
print("\nInformation about input tensors in ONNX:")
for i, input_tensor in enumerate(onnx_session.get_inputs()):
print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}")
# display information about output tensors in ONNX
print("\nInformation about output tensors in ONNX:")
for i, output_tensor in enumerate(onnx_session.get_outputs()):
print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}")
# 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)
print("\nAccuracy of NearestCentroid model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.87 0.92 0.89 50
Python 2 0.91 0.86 0.89 50
Python
Python accuracy 0.93 150
Python macro avg 0.93 0.93 0.93 150
Python weighted avg 0.93 0.93 0.93 150
Python
"Errors" sekmesinde, ONNX formatına dönüştürme hatalarına ilişkin mesajlar görüntülenir:
onnx_model = convert_topology( convert.py 208 1
topology.convert_operators(container=container, verbose=verbose) _topology.py 1532 1
self.call_shape_calculator(operator) _topology.py 1348 1
operator.infer_types() _topology.py 1163 1
raise MissingShapeCalculator( _topology.py 629 1
skl2onnx.common.exceptions.MissingShapeCalculator: Unable to find a shape calculator for type '<class 'sklearn.neighbors._nearest_centroid.NearestCentroid'>'. _topology.py 629 1
It usually means the pipeline being converted contains a _topology.py 629 1
transformer or a predictor with no corresponding converter _topology.py 629 1
implemented in sklearn-onnx. If the converted is implemented _topology.py 629 1
in another library, you need to register _topology.py 629 1
the converted so that it can be used by sklearn-onnx (function _topology.py 629 1
update_registered_converter). If the model is not yet covered _topology.py 629 1
by sklearn-onnx, you may raise an issue to _topology.py 629 1
https://github.com/onnx/sklearn-onnx/issues _topology.py 629 1
to get the converter implemented or even contribute to the _topology.py 629 1
project. If the model is a custom model, a new converter must _topology.py 629 1
be implemented. Examples can be found in the gallery. _topology.py 629 1
Iris_NearestCentroid.py finished in 2131 ms 19 1
2.29.6. Quadratic Discriminant Analysis Classifier
Quadratic Discriminant Analysis (QDA), verileri sınıflara ayırmak için olasılıksal bir model kullanan bir sınıflandırma yöntemidir. Linear Discriminant Analysis (LDA) yönteminin bir genellemesidir ve her bir sınıf içindeki özellik kovaryanslarının dikkate alınmasına izin verir. QDA'nın ana fikri, her sınıf için özellik dağılımını modellemek ve daha sonra yeni nesneleri sınıflandırmak için bu dağılımı kullanmaktır.
QDA süreci:
- Her sınıf için özelliklerin ortalaması ve kovaryans matrisi gibi dağılım parametreleri hesaplanır. Bu parametreler, her sınıf için eğitim verilerine dayalı olarak hesaplanır.
- Elde edilen parametreler kullanılarak, her bir sınıf için olasılık yoğunlukları çok değişkenli normal dağılım (veya kuadratik bir dağılım fonksiyonu) kullanılarak hesaplanabilir.
- Yeni bir nesne sınıflandırılırken, her sınıf için olasılık yoğunluk değerleri hesaplanır ve nesne en yüksek olasılığa sahip sınıfa atanır.
Quadratic Discriminant Analysis’in (QDA) avantajları:
- Özellik kovaryanslarını dikkate alır: QDA, LDA'dan daha esnektir çünkü farklı sınıflar için farklı kovaryans matrislerine izin verir, bu da onu farklı veri yapılarına daha uyarlanabilir hale getirir.
- Doğrusal olmayan sınırlar için uygundur: QDA, sınıflar arasındaki karmaşık ve doğrusal olmayan sınırları modelleme yeteneğine sahiptir.
- Dengesiz verilere karşı dayanıklıdır: QDA, dengesiz sınıflara sahip görevlerde iyi performans gösterebilir.
Quadratic Discriminant Analysis’in (QDA) sınırlamaları:
- Hesaplama karmaşıklığı: QDA, kovaryans matrisleri de dahil olmak üzere her sınıf için parametrelerin hesaplanmasını gerektirir ve bu da büyük veri kümelerinde hesaplama açısından maliyetli olabilir.
- Sınırlı veri: Veriler sınırlı olduğunda QDA daha az etkili çalışabilir ve parametre hesaplaması daha az hassas hale gelir.
- Normal dağılım varsayımı: QDA, verilerin normal bir dağılım izlediğini varsayar, ancak bu varsayım bazı veri türleri için geçerli olmayabilir.
- Aşırı uyum riski: Yetersiz eğitim verisi veya güçlü özellik kovaryansı ile QDA aşırı uyum sorunlarıyla karşılaşabilir.
Quadratic Discriminant Analysis (QDA), çeşitli veri türleri için uygun ve sınıflar içindeki özellik kovaryanslarını dikkate alabilen güçlü bir sınıflandırma yöntemidir. Bununla birlikte, kullanırken göz önünde bulundurulması gereken sınırlamaları da vardır.
2.29.6.1. Quadratic Discriminant Analysis Classifier modelini oluşturmak için kod
# Iris_QuadraticDiscriminantAnalysisClassifier.py
# The code demonstrates the process of training Quadratic Discriminant Analysis Classifier model on the Iris dataset, exporting it to ONNX format, and making predictions using the ONNX model.
# It also evaluates the accuracy of both the original model and the ONNX model.
# Copyright 2023, MetaQuotes Ltd.
# https://www.mql5.com
# import necessary libraries
from sklearn import datasets
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
from sklearn.metrics import accuracy_score, classification_report
from skl2onnx import convert_sklearn
from skl2onnx.common.data_types import FloatTensorType
import onnxruntime as ort
import numpy as np
import sys
# get the script path
script_path = sys.argv[0]
last_index = script_path.rfind("\\") + 1
data_path = script_path[0:last_index]
# load the Iris dataset
iris = datasets.load_iris()
X = iris.data
y = iris.target
# create a QuadraticDiscriminantAnalysis model
qda_model = QuadraticDiscriminantAnalysis()
# train the model on the entire dataset
qda_model.fit(X, y)
# predict classes for the entire dataset
y_pred = qda_model.predict(X)
# evaluate the model's accuracy
accuracy = accuracy_score(y, y_pred)
print("Accuracy of Quadratic Discriminant Analysis model:", accuracy)
# display the classification report
print("\nClassification Report:\n", classification_report(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(qda_model, initial_types=initial_type, target_opset=12)
# save the model to a file
onnx_filename = data_path + "qda_iris.onnx"
with open(onnx_filename, "wb") as f:
f.write(onnx_model.SerializeToString())
# print the path to the model
print(f"Model saved to {onnx_filename}")
# 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
# display information about input tensors in ONNX
print("\nInformation about input tensors in ONNX:")
for i, input_tensor in enumerate(onnx_session.get_inputs()):
print(f"{i + 1}. Name: {input_tensor.name}, Data Type: {input_tensor.type}, Shape: {input_tensor.shape}")
# display information about output tensors in ONNX
print("\nInformation about output tensors in ONNX:")
for i, output_tensor in enumerate(onnx_session.get_outputs()):
print(f"{i + 1}. Name: {output_tensor.name}, Data Type: {output_tensor.type}, Shape: {output_tensor.shape}")
# 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)
print("\nAccuracy of Quadratic Discriminant Analysis model in ONNX format:", accuracy_onnx)
Çıktı:
Python
Python Classification Report:
Python precision recall f1-score support
Python
Python 0 1.00 1.00 1.00 50
Python 1 0.98 0.96 0.97 50
Python 2 0.96 0.98 0.97 50
Python
Python accuracy 0.98 150
Python macro avg 0.98 0.98 0.98 150
Python weighted avg 0.98 0.98 0.98 150
Python
Python Model saved to C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\qda_iris.onnx
Bu kez, model ONNX formatında başarıyla kaydedildi. Ancak, yürütülürken Errors sekmesinde hatalar görüntülendi:
self._create_inference_session(providers, provider_options, disabled_optimizers) onnxruntime_inference_collection.py 383 1
sess = C.InferenceSession(session_options, self._model_path, True, self._read_config_from_model) onnxruntime_inference_collection.py 424 1
onnxruntime.capi.onnxruntime_pybind11_state.InvalidGraph: [ONNXRuntimeError] : 10 : INVALID_GRAPH : Load model from C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075\MQL5\Scripts\qda_iris.onnx failed:This is an invalid mode onnxruntime_inference_collection.py 424 1
Iris_QuadraticDiscriminantAnalysisClassifier.py finished in 2063 ms 5 1
Quadratic Discriminant Analysis Classifier modelinin ONNX'e dönüştürülmesinde hatayla karşılaşıldı.
Sonuç
Bu çalışmada, Scikit-learn kütüphanesinin 1.2.2 sürümünden yararlanarak iris veri kümesini kullanan 33 sınıflandırma modeli üzerinde araştırma yaptık.
1. Bu setten altı model ONNX formatına dönüştürülürken zorluklarla karşılaştı:
- DummyClassifier: Dummy Classifier;
- GaussianProcessClassifier: Gaussian Process Classifier;
- LabelPropagation : Label Propagation Classifier ;
- LabelSpreading : Label Spreading Classifier;
- NearestCentroid: Nearest Centroid Classifier;
- QuadraticDiscriminantAnalysis: Quadratic Discriminant Analysis Classifier.
Bu modellerin yapı ve/veya mantık açısından daha karmaşık olduğu ve ONNX formatına uyarlanmalarının ek çaba gerektirebileceği görülmektedir. Ayrıca, ONNX formatı için tam olarak desteklenmeyen veya uygun olmayan belirli veri yapılarını veya algoritmaları kullanmaları da olasıdır.
2. Kalan 27 model başarılı bir şekilde ONNX formatına dönüştürüldü ve doğruluklarının korunduğu gösterildi. Bu, ONNX'in makine öğrenimi modellerini kaydetmek ve geri yüklemek için bir araç olarak etkinliğini vurgulamaktadır. Performanslarını korurken farklı ortamlar ve uygulamalar arasında kolay bir şekilde model aktarımına olanak sağlar.
ONNX formatına başarıyla dönüştürülen modellerin tam listesi:
- SVC: Support Vector Classifier;
- LinearSVC: Linear Support Vector Classifier;
- NuSVC: Nu Support Vector Classifier;
- AdaBoostClassifier: Adaptive Boosting Classifier;
- BaggingClassifier: Bootstrap Aggregating Classifier;
- BernoulliNB: Bernoulli Naive Bayes Classifier;
- CategoricalNB: Categorical Naive Bayes Classifier;
- ComplementNB: Complement Naive Bayes Classifier;
- DecisionTreeClassifier: Decision Tree Classifier;
- ExtraTreeClassifier: Extra Tree Classifier;
- ExtraTreesClassifier: Extra Trees Classifier;
- GaussianNB: Gaussian Naive Bayes Classifier;
- GradientBoostingClassifier: Gradient Boosting Classifier;
- HistGradientBoostingClassifier: Histogram-Based Gradient Boosting Classifier;
- KNeighborsClassifier: k-Nearest Neighbors Classifier;
- LinearDiscriminantAnalysis: Linear Discriminant Analysis Classifier;
- LogisticRegression: Logistic Regression Classifier;
- LogisticRegressionCV: Logistic Regression Classifier with Cross-Validation;
- MLPClassifier: Multi-Layer Perceptron Classifier;
- MultinomialNB: Multinomial Naive Bayes Classifier;
- PassiveAggressiveClassifier: Passive-Aggressive Classifier;
- Perceptron: Perceptron Classifier;
- RadiusNeighborsClassifier: Radius Neighbors Classifier;
- RandomForestClassifier: Random Forest Classifier;
- RidgeClassifier: Ridge Classifier;
- RidgeClassifierCV: Ridge Classifier with Cross-Validation;
- SGDClassifier: Stochastic Gradient Descent Classifier.
3. Ayrıca, araştırma sırasında iris veri kümesi üzerinde üstün sınıflandırma performansı sergileyen modeller belirlenmiştir. Random Forest Classifier, Gradient Boosting Classifier, Bagging Classifier, Decision Tree Classifier, Extra Tree Classifier, Extra Trees Classifier ve Hist Gradient Boosting Classifier gibi sınıflandırma modelleri tahminlerde mükemmel doğruluk elde etmiştir. Bu, her bir iris örneğinin ait olduğu sınıfı doğru bir şekilde belirleyebilecekleri anlamına gelir.
Bu sonuçlar özellikle belirli sınıflandırma görevleri için en iyi modeli seçerken değerli olabilir. İris verileri üzerinde mükemmel doğruluk elde eden modeller, benzer verilerin analizini veya sınıflandırılmasını içeren görevler için mükemmel bir seçim olabilir.
Dolayısıyla bu araştırma, belirli görevler için doğru modeli seçmenin önemini vurgulamakta ve sınıflandırma görevleri için makine öğrenimi modellerini korumak ve uygulamak için ONNX kullanmanın avantajlarını ortaya koymaktadır.
Sonuç
Bu makalede, Scikit-learn sürüm 1.2.2 ile iris veri kümesini kullanarak 33 sınıflandırma modelini analiz ettik.
İncelediğimiz tüm modellerden altısının ONNX formatına dönüştürülmesinde zorluk yaşandı. Bu modeller şunlardır: Dummy Classifier, Gaussian Process Classifier, Label Propagation Classifier, Label Spreading Classifier, Nearest Centroid Classifier ve Quadratic Discriminant Analysis Classifier. Karmaşık yapıları veya mantıkları, ONNX formatına başarılı bir dönüşüm için muhtemelen ek uyarlama gerektirir.
Kalan 27 model başarılı bir şekilde ONNX formatına dönüştürüldü ve doğruluklarının korunduğu gösterildi. Bu, ONNX'in makine öğrenimi modellerini koruma ve geri yükleme konusundaki verimliliğini teyit etmektedir. Model performansını korurken taşınabilirlik sağlamaktadır.
Özellikle, Random Forest Classifier, Gradient Boosting Classifier, Bagging Classifier, Decision Tree Classifier, Extra Tree Classifier, Extra Trees Classifier ve Hist Gradient Boosting Classifier gibi bazı modeller, iris verilerini sınıflandırmada mükemmel doğruluk elde etmiştir. Bu modeller, yüksek doğruluğun kritik olduğu görevler için özellikle cazip olabilir.
Bu araştırma, belirli görevler için doğru modeli seçmenin önemini vurgulamakta ve sınıflandırma görevlerinde makine öğrenimi modellerini korumak ve uygulamak için ONNX’i kullanmanın faydalarını göstermektedir.
Makaledeki tüm kodlar MQL5\Shared Projects\Scikit.Classification.ONNX herkese açık projesinde de mevcuttur.
MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/13451
![Yeni Raylara Adım Atın: MQL5'te Özel Göstergeler](https://c.mql5.com/2/0/862_14.png)
![MQL5’i kullanarak çizgilerle nasıl çalışılır?](https://c.mql5.com/2/50/How_to_deal_with_lines_by_MQL5_Avatar.png)
![İşte Karışınızda Yeni MetaTrader 5 ve MQL5](https://c.mql5.com/2/0/851_25.jpg)
![Scikit-learn kütüphanesinin regresyon modelleri ve bunların ONNX'e aktarılması](https://c.mql5.com/2/59/Scikit_learn_to-ONNX_avatar.png)
![MQL5 - MetaTrader 5 müşteri terminalinde yerleşik ticaret stratejileri dili](https://c.mql5.com/i/registerlandings/logo-2.png)
- Ücretsiz ticaret uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz