diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..be2d180de32ed15adc756d6e4a389994b4fc3c8e
Binary files /dev/null and b/.DS_Store differ
diff --git a/examples/.DS_Store b/examples/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..e5a5d06f6fd3335cce658fa3ef6c0ea9d1163943
Binary files /dev/null and b/examples/.DS_Store differ
diff --git a/examples/decision_tree/Iris.csv b/examples/decision_tree/Iris.csv
new file mode 100644
index 0000000000000000000000000000000000000000..1bf42f25499fe73c70d9c767cb31163077c07e3e
--- /dev/null
+++ b/examples/decision_tree/Iris.csv
@@ -0,0 +1,151 @@
+Id,SepalLengthCm,SepalWidthCm,PetalLengthCm,PetalWidthCm,Species
+1,5.1,3.5,1.4,0.2,Iris-setosa
+2,4.9,3.0,1.4,0.2,Iris-setosa
+3,4.7,3.2,1.3,0.2,Iris-setosa
+4,4.6,3.1,1.5,0.2,Iris-setosa
+5,5.0,3.6,1.4,0.2,Iris-setosa
+6,5.4,3.9,1.7,0.4,Iris-setosa
+7,4.6,3.4,1.4,0.3,Iris-setosa
+8,5.0,3.4,1.5,0.2,Iris-setosa
+9,4.4,2.9,1.4,0.2,Iris-setosa
+10,4.9,3.1,1.5,0.1,Iris-setosa
+11,5.4,3.7,1.5,0.2,Iris-setosa
+12,4.8,3.4,1.6,0.2,Iris-setosa
+13,4.8,3.0,1.4,0.1,Iris-setosa
+14,4.3,3.0,1.1,0.1,Iris-setosa
+15,5.8,4.0,1.2,0.2,Iris-setosa
+16,5.7,4.4,1.5,0.4,Iris-setosa
+17,5.4,3.9,1.3,0.4,Iris-setosa
+18,5.1,3.5,1.4,0.3,Iris-setosa
+19,5.7,3.8,1.7,0.3,Iris-setosa
+20,5.1,3.8,1.5,0.3,Iris-setosa
+21,5.4,3.4,1.7,0.2,Iris-setosa
+22,5.1,3.7,1.5,0.4,Iris-setosa
+23,4.6,3.6,1.0,0.2,Iris-setosa
+24,5.1,3.3,1.7,0.5,Iris-setosa
+25,4.8,3.4,1.9,0.2,Iris-setosa
+26,5.0,3.0,1.6,0.2,Iris-setosa
+27,5.0,3.4,1.6,0.4,Iris-setosa
+28,5.2,3.5,1.5,0.2,Iris-setosa
+29,5.2,3.4,1.4,0.2,Iris-setosa
+30,4.7,3.2,1.6,0.2,Iris-setosa
+31,4.8,3.1,1.6,0.2,Iris-setosa
+32,5.4,3.4,1.5,0.4,Iris-setosa
+33,5.2,4.1,1.5,0.1,Iris-setosa
+34,5.5,4.2,1.4,0.2,Iris-setosa
+35,4.9,3.1,1.5,0.1,Iris-setosa
+36,5.0,3.2,1.2,0.2,Iris-setosa
+37,5.5,3.5,1.3,0.2,Iris-setosa
+38,4.9,3.1,1.5,0.1,Iris-setosa
+39,4.4,3.0,1.3,0.2,Iris-setosa
+40,5.1,3.4,1.5,0.2,Iris-setosa
+41,5.0,3.5,1.3,0.3,Iris-setosa
+42,4.5,2.3,1.3,0.3,Iris-setosa
+43,4.4,3.2,1.3,0.2,Iris-setosa
+44,5.0,3.5,1.6,0.6,Iris-setosa
+45,5.1,3.8,1.9,0.4,Iris-setosa
+46,4.8,3.0,1.4,0.3,Iris-setosa
+47,5.1,3.8,1.6,0.2,Iris-setosa
+48,4.6,3.2,1.4,0.2,Iris-setosa
+49,5.3,3.7,1.5,0.2,Iris-setosa
+50,5.0,3.3,1.4,0.2,Iris-setosa
+51,7.0,3.2,4.7,1.4,Iris-versicolor
+52,6.4,3.2,4.5,1.5,Iris-versicolor
+53,6.9,3.1,4.9,1.5,Iris-versicolor
+54,5.5,2.3,4.0,1.3,Iris-versicolor
+55,6.5,2.8,4.6,1.5,Iris-versicolor
+56,5.7,2.8,4.5,1.3,Iris-versicolor
+57,6.3,3.3,4.7,1.6,Iris-versicolor
+58,4.9,2.4,3.3,1.0,Iris-versicolor
+59,6.6,2.9,4.6,1.3,Iris-versicolor
+60,5.2,2.7,3.9,1.4,Iris-versicolor
+61,5.0,2.0,3.5,1.0,Iris-versicolor
+62,5.9,3.0,4.2,1.5,Iris-versicolor
+63,6.0,2.2,4.0,1.0,Iris-versicolor
+64,6.1,2.9,4.7,1.4,Iris-versicolor
+65,5.6,2.9,3.6,1.3,Iris-versicolor
+66,6.7,3.1,4.4,1.4,Iris-versicolor
+67,5.6,3.0,4.5,1.5,Iris-versicolor
+68,5.8,2.7,4.1,1.0,Iris-versicolor
+69,6.2,2.2,4.5,1.5,Iris-versicolor
+70,5.6,2.5,3.9,1.1,Iris-versicolor
+71,5.9,3.2,4.8,1.8,Iris-versicolor
+72,6.1,2.8,4.0,1.3,Iris-versicolor
+73,6.3,2.5,4.9,1.5,Iris-versicolor
+74,6.1,2.8,4.7,1.2,Iris-versicolor
+75,6.4,2.9,4.3,1.3,Iris-versicolor
+76,6.6,3.0,4.4,1.4,Iris-versicolor
+77,6.8,2.8,4.8,1.4,Iris-versicolor
+78,6.7,3.0,5.0,1.7,Iris-versicolor
+79,6.0,2.9,4.5,1.5,Iris-versicolor
+80,5.7,2.6,3.5,1.0,Iris-versicolor
+81,5.5,2.4,3.8,1.1,Iris-versicolor
+82,5.5,2.4,3.7,1.0,Iris-versicolor
+83,5.8,2.7,3.9,1.2,Iris-versicolor
+84,6.0,2.7,5.1,1.6,Iris-versicolor
+85,5.4,3.0,4.5,1.5,Iris-versicolor
+86,6.0,3.4,4.5,1.6,Iris-versicolor
+87,6.7,3.1,4.7,1.5,Iris-versicolor
+88,6.3,2.3,4.4,1.3,Iris-versicolor
+89,5.6,3.0,4.1,1.3,Iris-versicolor
+90,5.5,2.5,4.0,1.3,Iris-versicolor
+91,5.5,2.6,4.4,1.2,Iris-versicolor
+92,6.1,3.0,4.6,1.4,Iris-versicolor
+93,5.8,2.6,4.0,1.2,Iris-versicolor
+94,5.0,2.3,3.3,1.0,Iris-versicolor
+95,5.6,2.7,4.2,1.3,Iris-versicolor
+96,5.7,3.0,4.2,1.2,Iris-versicolor
+97,5.7,2.9,4.2,1.3,Iris-versicolor
+98,6.2,2.9,4.3,1.3,Iris-versicolor
+99,5.1,2.5,3.0,1.1,Iris-versicolor
+100,5.7,2.8,4.1,1.3,Iris-versicolor
+101,6.3,3.3,6.0,2.5,Iris-virginica
+102,5.8,2.7,5.1,1.9,Iris-virginica
+103,7.1,3.0,5.9,2.1,Iris-virginica
+104,6.3,2.9,5.6,1.8,Iris-virginica
+105,6.5,3.0,5.8,2.2,Iris-virginica
+106,7.6,3.0,6.6,2.1,Iris-virginica
+107,4.9,2.5,4.5,1.7,Iris-virginica
+108,7.3,2.9,6.3,1.8,Iris-virginica
+109,6.7,2.5,5.8,1.8,Iris-virginica
+110,7.2,3.6,6.1,2.5,Iris-virginica
+111,6.5,3.2,5.1,2.0,Iris-virginica
+112,6.4,2.7,5.3,1.9,Iris-virginica
+113,6.8,3.0,5.5,2.1,Iris-virginica
+114,5.7,2.5,5.0,2.0,Iris-virginica
+115,5.8,2.8,5.1,2.4,Iris-virginica
+116,6.4,3.2,5.3,2.3,Iris-virginica
+117,6.5,3.0,5.5,1.8,Iris-virginica
+118,7.7,3.8,6.7,2.2,Iris-virginica
+119,7.7,2.6,6.9,2.3,Iris-virginica
+120,6.0,2.2,5.0,1.5,Iris-virginica
+121,6.9,3.2,5.7,2.3,Iris-virginica
+122,5.6,2.8,4.9,2.0,Iris-virginica
+123,7.7,2.8,6.7,2.0,Iris-virginica
+124,6.3,2.7,4.9,1.8,Iris-virginica
+125,6.7,3.3,5.7,2.1,Iris-virginica
+126,7.2,3.2,6.0,1.8,Iris-virginica
+127,6.2,2.8,4.8,1.8,Iris-virginica
+128,6.1,3.0,4.9,1.8,Iris-virginica
+129,6.4,2.8,5.6,2.1,Iris-virginica
+130,7.2,3.0,5.8,1.6,Iris-virginica
+131,7.4,2.8,6.1,1.9,Iris-virginica
+132,7.9,3.8,6.4,2.0,Iris-virginica
+133,6.4,2.8,5.6,2.2,Iris-virginica
+134,6.3,2.8,5.1,1.5,Iris-virginica
+135,6.1,2.6,5.6,1.4,Iris-virginica
+136,7.7,3.0,6.1,2.3,Iris-virginica
+137,6.3,3.4,5.6,2.4,Iris-virginica
+138,6.4,3.1,5.5,1.8,Iris-virginica
+139,6.0,3.0,4.8,1.8,Iris-virginica
+140,6.9,3.1,5.4,2.1,Iris-virginica
+141,6.7,3.1,5.6,2.4,Iris-virginica
+142,6.9,3.1,5.1,2.3,Iris-virginica
+143,5.8,2.7,5.1,1.9,Iris-virginica
+144,6.8,3.2,5.9,2.3,Iris-virginica
+145,6.7,3.3,5.7,2.5,Iris-virginica
+146,6.7,3.0,5.2,2.3,Iris-virginica
+147,6.3,2.5,5.0,1.9,Iris-virginica
+148,6.5,3.0,5.2,2.0,Iris-virginica
+149,6.2,3.4,5.4,2.3,Iris-virginica
+150,5.9,3.0,5.1,1.8,Iris-virginica
diff --git a/examples/decision_tree/main.html b/examples/decision_tree/main.html
new file mode 100644
index 0000000000000000000000000000000000000000..858b9385a06985f596ad9a6e0facc86b8d9ac9c6
--- /dev/null
+++ b/examples/decision_tree/main.html
@@ -0,0 +1,85 @@
+
+
+
+
+<!DOCTYPE html>
+<html lang="en">
+
+ <head>
+
+ <meta charset="utf-8">
+ <title>Bokeh Plot</title>
+
+
+
+
+
+
+
+ <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js"></script>
+ <script type="text/javascript">
+ Bokeh.set_log_level("info");
+ </script>
+
+
+
+
+ </head>
+
+
+ <body>
+
+
+
+
+
+
+ <div class="bk-root" id="0404cce4-d3b9-4e96-88e7-e633d01327c4" data-root-id="1048"></div>
+
+
+
+
+
+ <script type="application/json" id="1217">
+ {"161c1ee2-b4f4-43e7-9389-e8d99579e12d":{"defs":[],"roots":{"references":[{"attributes":{"factors":["1 > 0.80","1 > 0.68","2 <= -1.38","-0.03 < 1 <= 0.64"]},"id":"1051","type":"FactorRange"},{"attributes":{"axis":{"id":"1059"},"coordinates":null,"group":null,"ticker":null},"id":"1061","type":"Grid"},{"attributes":{"source":{"id":"1080"}},"id":"1085","type":"CDSView"},{"attributes":{},"id":"1057","type":"LinearScale"},{"attributes":{"coordinates":null,"formatter":{"id":"1092"},"group":null,"major_label_policy":{"id":"1093"},"ticker":{"id":"1060"}},"id":"1059","type":"CategoricalAxis"},{"attributes":{"fill_color":{"value":"#fc8d59"},"hatch_color":{"value":"#fc8d59"},"line_color":{"value":"#fc8d59"},"top":{"field":"top"},"width":{"value":0.5},"x":{"field":"x"}},"id":"1081","type":"VBar"},{"attributes":{"below":[{"id":"1059"}],"center":[{"id":"1061"},{"id":"1065"}],"height":400,"left":[{"id":"1062"}],"renderers":[{"id":"1084"}],"title":{"id":"1049"},"toolbar":{"id":"1073"},"x_range":{"id":"1051"},"x_scale":{"id":"1055"},"y_range":{"id":"1053"},"y_scale":{"id":"1057"}},"id":"1048","subtype":"Figure","type":"Plot"},{"attributes":{"coordinates":null,"group":null,"text":"Feature Importance Scores"},"id":"1049","type":"Title"},{"attributes":{"fill_alpha":{"value":0.1},"fill_color":{"value":"#fc8d59"},"hatch_alpha":{"value":0.1},"hatch_color":{"value":"#fc8d59"},"line_alpha":{"value":0.1},"line_color":{"value":"#fc8d59"},"top":{"field":"top"},"width":{"value":0.5},"x":{"field":"x"}},"id":"1082","type":"VBar"},{"attributes":{"coordinates":null,"data_source":{"id":"1080"},"glyph":{"id":"1081"},"group":null,"hover_glyph":null,"muted_glyph":{"id":"1083"},"nonselection_glyph":{"id":"1082"},"view":{"id":"1085"}},"id":"1084","type":"GlyphRenderer"},{"attributes":{},"id":"1069","type":"SaveTool"},{"attributes":{},"id":"1055","type":"CategoricalScale"},{"attributes":{"tools":[{"id":"1066"},{"id":"1067"},{"id":"1068"},{"id":"1069"},{"id":"1070"},{"id":"1071"}]},"id":"1073","type":"Toolbar"},{"attributes":{"fill_alpha":{"value":0.2},"fill_color":{"value":"#fc8d59"},"hatch_alpha":{"value":0.2},"hatch_color":{"value":"#fc8d59"},"line_alpha":{"value":0.2},"line_color":{"value":"#fc8d59"},"top":{"field":"top"},"width":{"value":0.5},"x":{"field":"x"}},"id":"1083","type":"VBar"},{"attributes":{},"id":"1060","type":"CategoricalTicker"},{"attributes":{},"id":"1066","type":"PanTool"},{"attributes":{},"id":"1053","type":"DataRange1d"},{"attributes":{"data":{"top":[0.9182248108408918,0.010593237834966903,-0.0027127181247810447,-0.001100310815155346],"x":["1 > 0.80","1 > 0.68","2 <= -1.38","-0.03 < 1 <= 0.64"]},"selected":{"id":"1095"},"selection_policy":{"id":"1094"}},"id":"1080","type":"ColumnDataSource"},{"attributes":{},"id":"1070","type":"ResetTool"},{"attributes":{},"id":"1067","type":"WheelZoomTool"},{"attributes":{},"id":"1089","type":"BasicTickFormatter"},{"attributes":{"bottom_units":"screen","coordinates":null,"fill_alpha":0.5,"fill_color":"lightgrey","group":null,"left_units":"screen","level":"overlay","line_alpha":1.0,"line_color":"black","line_dash":[4,4],"line_width":2,"right_units":"screen","syncable":false,"top_units":"screen"},"id":"1072","type":"BoxAnnotation"},{"attributes":{"overlay":{"id":"1072"}},"id":"1068","type":"BoxZoomTool"},{"attributes":{"coordinates":null,"formatter":{"id":"1089"},"group":null,"major_label_policy":{"id":"1090"},"ticker":{"id":"1063"}},"id":"1062","type":"LinearAxis"},{"attributes":{},"id":"1090","type":"AllLabels"},{"attributes":{},"id":"1071","type":"HelpTool"},{"attributes":{},"id":"1093","type":"AllLabels"},{"attributes":{},"id":"1092","type":"CategoricalTickFormatter"},{"attributes":{},"id":"1063","type":"BasicTicker"},{"attributes":{},"id":"1094","type":"UnionRenderers"},{"attributes":{"axis":{"id":"1062"},"coordinates":null,"dimension":1,"group":null,"ticker":null},"id":"1065","type":"Grid"},{"attributes":{},"id":"1095","type":"Selection"}],"root_ids":["1048"]},"title":"Bokeh Application","version":"2.4.2"}}
+ </script>
+ <script type="text/javascript">
+ (function() {
+ const fn = function() {
+ Bokeh.safely(function() {
+ (function(root) {
+ function embed_document(root) {
+
+ const docs_json = document.getElementById('1217').textContent;
+ const render_items = [{"docid":"161c1ee2-b4f4-43e7-9389-e8d99579e12d","root_ids":["1048"],"roots":{"1048":"0404cce4-d3b9-4e96-88e7-e633d01327c4"}}];
+ root.Bokeh.embed.embed_items(docs_json, render_items);
+
+ }
+ if (root.Bokeh !== undefined) {
+ embed_document(root);
+ } else {
+ let attempts = 0;
+ const timer = setInterval(function(root) {
+ if (root.Bokeh !== undefined) {
+ clearInterval(timer);
+ embed_document(root);
+ } else {
+ attempts++;
+ if (attempts > 100) {
+ clearInterval(timer);
+ console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
+ }
+ }
+ }, 10, root)
+ }
+ })(window);
+ });
+ };
+ if (document.readyState != "loading") fn();
+ else document.addEventListener("DOMContentLoaded", fn);
+ })();
+ </script>
+
+ </body>
+
+</html>
\ No newline at end of file
diff --git a/examples/decision_tree/main.py b/examples/decision_tree/main.py
index 3ca1536be4eebada06be154132b6a7837f20e5e1..1b82988a33f5717f934beed0f664cebd47c0a3b5 100644
--- a/examples/decision_tree/main.py
+++ b/examples/decision_tree/main.py
@@ -1,41 +1,36 @@
import numpy as np
-
-from sklearn.tree import export_graphviz
-from subprocess import call
+# import pandas as pd
from synthetic import *
-from data_vis import *
+from data_vis import vis_synthetic
+from data_vis import decisionTreemodel
+from data_vis import logisticRegressionmodel
import config as config
+from modelling import *
from bokeh.io import curdoc
-from bokeh.models import ColumnDataSource, Select, Slider, Plot, Scatter, Row, Column
+from bokeh.models import ColumnDataSource, Row
from bokeh.palettes import Spectral6
np.random.seed(0)
-data = SyntheticData()
+data = SyntheticData(shuffle=False)
-config.x, config.y = data.generator()
+config.X_train, config.X_test, config.y_train, config.y_test = data.generator()
-config.spectral = np.hstack([Spectral6] * 20)
+testModel = decisionTreemodel(config.X_train, config.X_test, config.y_train, config.y_test, 9)
-colors = [config.spectral[i] for i in config.y]
-config.source = ColumnDataSource(dict(x=config.x[:,0], y=config.x[:,1], colors=colors))
+#fit model using fit method on the model class
-b = vis_synthetic()
+config.spectral = np.hstack([Spectral6] * 20)
+
+colors = [config.spectral[i] for i in config.y_train]
-clf_algorithms = [
- 'Decision Tree'
-]
+config.source = ColumnDataSource(dict(x=config.X_train[:,0], y=config.X_train[:,1], colors=colors))
-algorithm_select = Select(value = 'Decision Tree',
- title='Select Algorithm:',
- width=200,
- options=clf_algorithms
- )
-# add to document
-curdoc().add_root(Row(config.inputs, b))
-curdoc().title = "Decision Tree"
+b = vis_synthetic()
+curdoc().add_root(Row(config.inputs, b, testModel)) #, text_input_widget, stext_output2))
+curdoc().title = "Decision Tree"
\ No newline at end of file
diff --git a/examples/log_regression/Iris.csv b/examples/log_regression/Iris.csv
new file mode 100644
index 0000000000000000000000000000000000000000..1bf42f25499fe73c70d9c767cb31163077c07e3e
--- /dev/null
+++ b/examples/log_regression/Iris.csv
@@ -0,0 +1,151 @@
+Id,SepalLengthCm,SepalWidthCm,PetalLengthCm,PetalWidthCm,Species
+1,5.1,3.5,1.4,0.2,Iris-setosa
+2,4.9,3.0,1.4,0.2,Iris-setosa
+3,4.7,3.2,1.3,0.2,Iris-setosa
+4,4.6,3.1,1.5,0.2,Iris-setosa
+5,5.0,3.6,1.4,0.2,Iris-setosa
+6,5.4,3.9,1.7,0.4,Iris-setosa
+7,4.6,3.4,1.4,0.3,Iris-setosa
+8,5.0,3.4,1.5,0.2,Iris-setosa
+9,4.4,2.9,1.4,0.2,Iris-setosa
+10,4.9,3.1,1.5,0.1,Iris-setosa
+11,5.4,3.7,1.5,0.2,Iris-setosa
+12,4.8,3.4,1.6,0.2,Iris-setosa
+13,4.8,3.0,1.4,0.1,Iris-setosa
+14,4.3,3.0,1.1,0.1,Iris-setosa
+15,5.8,4.0,1.2,0.2,Iris-setosa
+16,5.7,4.4,1.5,0.4,Iris-setosa
+17,5.4,3.9,1.3,0.4,Iris-setosa
+18,5.1,3.5,1.4,0.3,Iris-setosa
+19,5.7,3.8,1.7,0.3,Iris-setosa
+20,5.1,3.8,1.5,0.3,Iris-setosa
+21,5.4,3.4,1.7,0.2,Iris-setosa
+22,5.1,3.7,1.5,0.4,Iris-setosa
+23,4.6,3.6,1.0,0.2,Iris-setosa
+24,5.1,3.3,1.7,0.5,Iris-setosa
+25,4.8,3.4,1.9,0.2,Iris-setosa
+26,5.0,3.0,1.6,0.2,Iris-setosa
+27,5.0,3.4,1.6,0.4,Iris-setosa
+28,5.2,3.5,1.5,0.2,Iris-setosa
+29,5.2,3.4,1.4,0.2,Iris-setosa
+30,4.7,3.2,1.6,0.2,Iris-setosa
+31,4.8,3.1,1.6,0.2,Iris-setosa
+32,5.4,3.4,1.5,0.4,Iris-setosa
+33,5.2,4.1,1.5,0.1,Iris-setosa
+34,5.5,4.2,1.4,0.2,Iris-setosa
+35,4.9,3.1,1.5,0.1,Iris-setosa
+36,5.0,3.2,1.2,0.2,Iris-setosa
+37,5.5,3.5,1.3,0.2,Iris-setosa
+38,4.9,3.1,1.5,0.1,Iris-setosa
+39,4.4,3.0,1.3,0.2,Iris-setosa
+40,5.1,3.4,1.5,0.2,Iris-setosa
+41,5.0,3.5,1.3,0.3,Iris-setosa
+42,4.5,2.3,1.3,0.3,Iris-setosa
+43,4.4,3.2,1.3,0.2,Iris-setosa
+44,5.0,3.5,1.6,0.6,Iris-setosa
+45,5.1,3.8,1.9,0.4,Iris-setosa
+46,4.8,3.0,1.4,0.3,Iris-setosa
+47,5.1,3.8,1.6,0.2,Iris-setosa
+48,4.6,3.2,1.4,0.2,Iris-setosa
+49,5.3,3.7,1.5,0.2,Iris-setosa
+50,5.0,3.3,1.4,0.2,Iris-setosa
+51,7.0,3.2,4.7,1.4,Iris-versicolor
+52,6.4,3.2,4.5,1.5,Iris-versicolor
+53,6.9,3.1,4.9,1.5,Iris-versicolor
+54,5.5,2.3,4.0,1.3,Iris-versicolor
+55,6.5,2.8,4.6,1.5,Iris-versicolor
+56,5.7,2.8,4.5,1.3,Iris-versicolor
+57,6.3,3.3,4.7,1.6,Iris-versicolor
+58,4.9,2.4,3.3,1.0,Iris-versicolor
+59,6.6,2.9,4.6,1.3,Iris-versicolor
+60,5.2,2.7,3.9,1.4,Iris-versicolor
+61,5.0,2.0,3.5,1.0,Iris-versicolor
+62,5.9,3.0,4.2,1.5,Iris-versicolor
+63,6.0,2.2,4.0,1.0,Iris-versicolor
+64,6.1,2.9,4.7,1.4,Iris-versicolor
+65,5.6,2.9,3.6,1.3,Iris-versicolor
+66,6.7,3.1,4.4,1.4,Iris-versicolor
+67,5.6,3.0,4.5,1.5,Iris-versicolor
+68,5.8,2.7,4.1,1.0,Iris-versicolor
+69,6.2,2.2,4.5,1.5,Iris-versicolor
+70,5.6,2.5,3.9,1.1,Iris-versicolor
+71,5.9,3.2,4.8,1.8,Iris-versicolor
+72,6.1,2.8,4.0,1.3,Iris-versicolor
+73,6.3,2.5,4.9,1.5,Iris-versicolor
+74,6.1,2.8,4.7,1.2,Iris-versicolor
+75,6.4,2.9,4.3,1.3,Iris-versicolor
+76,6.6,3.0,4.4,1.4,Iris-versicolor
+77,6.8,2.8,4.8,1.4,Iris-versicolor
+78,6.7,3.0,5.0,1.7,Iris-versicolor
+79,6.0,2.9,4.5,1.5,Iris-versicolor
+80,5.7,2.6,3.5,1.0,Iris-versicolor
+81,5.5,2.4,3.8,1.1,Iris-versicolor
+82,5.5,2.4,3.7,1.0,Iris-versicolor
+83,5.8,2.7,3.9,1.2,Iris-versicolor
+84,6.0,2.7,5.1,1.6,Iris-versicolor
+85,5.4,3.0,4.5,1.5,Iris-versicolor
+86,6.0,3.4,4.5,1.6,Iris-versicolor
+87,6.7,3.1,4.7,1.5,Iris-versicolor
+88,6.3,2.3,4.4,1.3,Iris-versicolor
+89,5.6,3.0,4.1,1.3,Iris-versicolor
+90,5.5,2.5,4.0,1.3,Iris-versicolor
+91,5.5,2.6,4.4,1.2,Iris-versicolor
+92,6.1,3.0,4.6,1.4,Iris-versicolor
+93,5.8,2.6,4.0,1.2,Iris-versicolor
+94,5.0,2.3,3.3,1.0,Iris-versicolor
+95,5.6,2.7,4.2,1.3,Iris-versicolor
+96,5.7,3.0,4.2,1.2,Iris-versicolor
+97,5.7,2.9,4.2,1.3,Iris-versicolor
+98,6.2,2.9,4.3,1.3,Iris-versicolor
+99,5.1,2.5,3.0,1.1,Iris-versicolor
+100,5.7,2.8,4.1,1.3,Iris-versicolor
+101,6.3,3.3,6.0,2.5,Iris-virginica
+102,5.8,2.7,5.1,1.9,Iris-virginica
+103,7.1,3.0,5.9,2.1,Iris-virginica
+104,6.3,2.9,5.6,1.8,Iris-virginica
+105,6.5,3.0,5.8,2.2,Iris-virginica
+106,7.6,3.0,6.6,2.1,Iris-virginica
+107,4.9,2.5,4.5,1.7,Iris-virginica
+108,7.3,2.9,6.3,1.8,Iris-virginica
+109,6.7,2.5,5.8,1.8,Iris-virginica
+110,7.2,3.6,6.1,2.5,Iris-virginica
+111,6.5,3.2,5.1,2.0,Iris-virginica
+112,6.4,2.7,5.3,1.9,Iris-virginica
+113,6.8,3.0,5.5,2.1,Iris-virginica
+114,5.7,2.5,5.0,2.0,Iris-virginica
+115,5.8,2.8,5.1,2.4,Iris-virginica
+116,6.4,3.2,5.3,2.3,Iris-virginica
+117,6.5,3.0,5.5,1.8,Iris-virginica
+118,7.7,3.8,6.7,2.2,Iris-virginica
+119,7.7,2.6,6.9,2.3,Iris-virginica
+120,6.0,2.2,5.0,1.5,Iris-virginica
+121,6.9,3.2,5.7,2.3,Iris-virginica
+122,5.6,2.8,4.9,2.0,Iris-virginica
+123,7.7,2.8,6.7,2.0,Iris-virginica
+124,6.3,2.7,4.9,1.8,Iris-virginica
+125,6.7,3.3,5.7,2.1,Iris-virginica
+126,7.2,3.2,6.0,1.8,Iris-virginica
+127,6.2,2.8,4.8,1.8,Iris-virginica
+128,6.1,3.0,4.9,1.8,Iris-virginica
+129,6.4,2.8,5.6,2.1,Iris-virginica
+130,7.2,3.0,5.8,1.6,Iris-virginica
+131,7.4,2.8,6.1,1.9,Iris-virginica
+132,7.9,3.8,6.4,2.0,Iris-virginica
+133,6.4,2.8,5.6,2.2,Iris-virginica
+134,6.3,2.8,5.1,1.5,Iris-virginica
+135,6.1,2.6,5.6,1.4,Iris-virginica
+136,7.7,3.0,6.1,2.3,Iris-virginica
+137,6.3,3.4,5.6,2.4,Iris-virginica
+138,6.4,3.1,5.5,1.8,Iris-virginica
+139,6.0,3.0,4.8,1.8,Iris-virginica
+140,6.9,3.1,5.4,2.1,Iris-virginica
+141,6.7,3.1,5.6,2.4,Iris-virginica
+142,6.9,3.1,5.1,2.3,Iris-virginica
+143,5.8,2.7,5.1,1.9,Iris-virginica
+144,6.8,3.2,5.9,2.3,Iris-virginica
+145,6.7,3.3,5.7,2.5,Iris-virginica
+146,6.7,3.0,5.2,2.3,Iris-virginica
+147,6.3,2.5,5.0,1.9,Iris-virginica
+148,6.5,3.0,5.2,2.0,Iris-virginica
+149,6.2,3.4,5.4,2.3,Iris-virginica
+150,5.9,3.0,5.1,1.8,Iris-virginica
diff --git a/examples/log_regression/main.html b/examples/log_regression/main.html
new file mode 100644
index 0000000000000000000000000000000000000000..858b9385a06985f596ad9a6e0facc86b8d9ac9c6
--- /dev/null
+++ b/examples/log_regression/main.html
@@ -0,0 +1,85 @@
+
+
+
+
+<!DOCTYPE html>
+<html lang="en">
+
+ <head>
+
+ <meta charset="utf-8">
+ <title>Bokeh Plot</title>
+
+
+
+
+
+
+
+ <script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js"></script>
+ <script type="text/javascript">
+ Bokeh.set_log_level("info");
+ </script>
+
+
+
+
+ </head>
+
+
+ <body>
+
+
+
+
+
+
+ <div class="bk-root" id="0404cce4-d3b9-4e96-88e7-e633d01327c4" data-root-id="1048"></div>
+
+
+
+
+
+ <script type="application/json" id="1217">
+ {"161c1ee2-b4f4-43e7-9389-e8d99579e12d":{"defs":[],"roots":{"references":[{"attributes":{"factors":["1 > 0.80","1 > 0.68","2 <= -1.38","-0.03 < 1 <= 0.64"]},"id":"1051","type":"FactorRange"},{"attributes":{"axis":{"id":"1059"},"coordinates":null,"group":null,"ticker":null},"id":"1061","type":"Grid"},{"attributes":{"source":{"id":"1080"}},"id":"1085","type":"CDSView"},{"attributes":{},"id":"1057","type":"LinearScale"},{"attributes":{"coordinates":null,"formatter":{"id":"1092"},"group":null,"major_label_policy":{"id":"1093"},"ticker":{"id":"1060"}},"id":"1059","type":"CategoricalAxis"},{"attributes":{"fill_color":{"value":"#fc8d59"},"hatch_color":{"value":"#fc8d59"},"line_color":{"value":"#fc8d59"},"top":{"field":"top"},"width":{"value":0.5},"x":{"field":"x"}},"id":"1081","type":"VBar"},{"attributes":{"below":[{"id":"1059"}],"center":[{"id":"1061"},{"id":"1065"}],"height":400,"left":[{"id":"1062"}],"renderers":[{"id":"1084"}],"title":{"id":"1049"},"toolbar":{"id":"1073"},"x_range":{"id":"1051"},"x_scale":{"id":"1055"},"y_range":{"id":"1053"},"y_scale":{"id":"1057"}},"id":"1048","subtype":"Figure","type":"Plot"},{"attributes":{"coordinates":null,"group":null,"text":"Feature Importance Scores"},"id":"1049","type":"Title"},{"attributes":{"fill_alpha":{"value":0.1},"fill_color":{"value":"#fc8d59"},"hatch_alpha":{"value":0.1},"hatch_color":{"value":"#fc8d59"},"line_alpha":{"value":0.1},"line_color":{"value":"#fc8d59"},"top":{"field":"top"},"width":{"value":0.5},"x":{"field":"x"}},"id":"1082","type":"VBar"},{"attributes":{"coordinates":null,"data_source":{"id":"1080"},"glyph":{"id":"1081"},"group":null,"hover_glyph":null,"muted_glyph":{"id":"1083"},"nonselection_glyph":{"id":"1082"},"view":{"id":"1085"}},"id":"1084","type":"GlyphRenderer"},{"attributes":{},"id":"1069","type":"SaveTool"},{"attributes":{},"id":"1055","type":"CategoricalScale"},{"attributes":{"tools":[{"id":"1066"},{"id":"1067"},{"id":"1068"},{"id":"1069"},{"id":"1070"},{"id":"1071"}]},"id":"1073","type":"Toolbar"},{"attributes":{"fill_alpha":{"value":0.2},"fill_color":{"value":"#fc8d59"},"hatch_alpha":{"value":0.2},"hatch_color":{"value":"#fc8d59"},"line_alpha":{"value":0.2},"line_color":{"value":"#fc8d59"},"top":{"field":"top"},"width":{"value":0.5},"x":{"field":"x"}},"id":"1083","type":"VBar"},{"attributes":{},"id":"1060","type":"CategoricalTicker"},{"attributes":{},"id":"1066","type":"PanTool"},{"attributes":{},"id":"1053","type":"DataRange1d"},{"attributes":{"data":{"top":[0.9182248108408918,0.010593237834966903,-0.0027127181247810447,-0.001100310815155346],"x":["1 > 0.80","1 > 0.68","2 <= -1.38","-0.03 < 1 <= 0.64"]},"selected":{"id":"1095"},"selection_policy":{"id":"1094"}},"id":"1080","type":"ColumnDataSource"},{"attributes":{},"id":"1070","type":"ResetTool"},{"attributes":{},"id":"1067","type":"WheelZoomTool"},{"attributes":{},"id":"1089","type":"BasicTickFormatter"},{"attributes":{"bottom_units":"screen","coordinates":null,"fill_alpha":0.5,"fill_color":"lightgrey","group":null,"left_units":"screen","level":"overlay","line_alpha":1.0,"line_color":"black","line_dash":[4,4],"line_width":2,"right_units":"screen","syncable":false,"top_units":"screen"},"id":"1072","type":"BoxAnnotation"},{"attributes":{"overlay":{"id":"1072"}},"id":"1068","type":"BoxZoomTool"},{"attributes":{"coordinates":null,"formatter":{"id":"1089"},"group":null,"major_label_policy":{"id":"1090"},"ticker":{"id":"1063"}},"id":"1062","type":"LinearAxis"},{"attributes":{},"id":"1090","type":"AllLabels"},{"attributes":{},"id":"1071","type":"HelpTool"},{"attributes":{},"id":"1093","type":"AllLabels"},{"attributes":{},"id":"1092","type":"CategoricalTickFormatter"},{"attributes":{},"id":"1063","type":"BasicTicker"},{"attributes":{},"id":"1094","type":"UnionRenderers"},{"attributes":{"axis":{"id":"1062"},"coordinates":null,"dimension":1,"group":null,"ticker":null},"id":"1065","type":"Grid"},{"attributes":{},"id":"1095","type":"Selection"}],"root_ids":["1048"]},"title":"Bokeh Application","version":"2.4.2"}}
+ </script>
+ <script type="text/javascript">
+ (function() {
+ const fn = function() {
+ Bokeh.safely(function() {
+ (function(root) {
+ function embed_document(root) {
+
+ const docs_json = document.getElementById('1217').textContent;
+ const render_items = [{"docid":"161c1ee2-b4f4-43e7-9389-e8d99579e12d","root_ids":["1048"],"roots":{"1048":"0404cce4-d3b9-4e96-88e7-e633d01327c4"}}];
+ root.Bokeh.embed.embed_items(docs_json, render_items);
+
+ }
+ if (root.Bokeh !== undefined) {
+ embed_document(root);
+ } else {
+ let attempts = 0;
+ const timer = setInterval(function(root) {
+ if (root.Bokeh !== undefined) {
+ clearInterval(timer);
+ embed_document(root);
+ } else {
+ attempts++;
+ if (attempts > 100) {
+ clearInterval(timer);
+ console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
+ }
+ }
+ }, 10, root)
+ }
+ })(window);
+ });
+ };
+ if (document.readyState != "loading") fn();
+ else document.addEventListener("DOMContentLoaded", fn);
+ })();
+ </script>
+
+ </body>
+
+</html>
\ No newline at end of file
diff --git a/examples/log_regression/main.py b/examples/log_regression/main.py
index 30a7d2910cfacbd06d7c0d2d21292034264678b7..13284a57e63de2b9bb9a635c06b09d896fd716d5 100644
--- a/examples/log_regression/main.py
+++ b/examples/log_regression/main.py
@@ -418,4 +418,4 @@ hist & overlap
#return sm
#print(histogram_intersection(flattened1, flattened2, flattened3, flattened4))
-#print(np.sum(np.minimum(A,B)))
+#print(np.sum(np.minimum(A,B)))
\ No newline at end of file
diff --git a/examples/log_regression/theme.yaml b/examples/log_regression/theme.yaml
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ce434d51aee270c4301f01b4867133750d8ee485 100644
--- a/examples/log_regression/theme.yaml
+++ b/examples/log_regression/theme.yaml
@@ -0,0 +1,12 @@
+attrs:
+ Figure:
+ width: 400
+ height: 400
+ background_fill_color: 'lightgrey'
+ background_fill_alpha: 0.2
+
+ Grid:
+ grid_line_color: null
+
+ Title:
+ text_font_size: '13px'
\ No newline at end of file
diff --git a/src/.DS_Store b/src/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..dbb4114a479af11d9b93b8899626c20655c4038c
Binary files /dev/null and b/src/.DS_Store differ
diff --git a/src/Iris2.csv b/src/Iris2.csv
new file mode 100644
index 0000000000000000000000000000000000000000..1bf42f25499fe73c70d9c767cb31163077c07e3e
--- /dev/null
+++ b/src/Iris2.csv
@@ -0,0 +1,151 @@
+Id,SepalLengthCm,SepalWidthCm,PetalLengthCm,PetalWidthCm,Species
+1,5.1,3.5,1.4,0.2,Iris-setosa
+2,4.9,3.0,1.4,0.2,Iris-setosa
+3,4.7,3.2,1.3,0.2,Iris-setosa
+4,4.6,3.1,1.5,0.2,Iris-setosa
+5,5.0,3.6,1.4,0.2,Iris-setosa
+6,5.4,3.9,1.7,0.4,Iris-setosa
+7,4.6,3.4,1.4,0.3,Iris-setosa
+8,5.0,3.4,1.5,0.2,Iris-setosa
+9,4.4,2.9,1.4,0.2,Iris-setosa
+10,4.9,3.1,1.5,0.1,Iris-setosa
+11,5.4,3.7,1.5,0.2,Iris-setosa
+12,4.8,3.4,1.6,0.2,Iris-setosa
+13,4.8,3.0,1.4,0.1,Iris-setosa
+14,4.3,3.0,1.1,0.1,Iris-setosa
+15,5.8,4.0,1.2,0.2,Iris-setosa
+16,5.7,4.4,1.5,0.4,Iris-setosa
+17,5.4,3.9,1.3,0.4,Iris-setosa
+18,5.1,3.5,1.4,0.3,Iris-setosa
+19,5.7,3.8,1.7,0.3,Iris-setosa
+20,5.1,3.8,1.5,0.3,Iris-setosa
+21,5.4,3.4,1.7,0.2,Iris-setosa
+22,5.1,3.7,1.5,0.4,Iris-setosa
+23,4.6,3.6,1.0,0.2,Iris-setosa
+24,5.1,3.3,1.7,0.5,Iris-setosa
+25,4.8,3.4,1.9,0.2,Iris-setosa
+26,5.0,3.0,1.6,0.2,Iris-setosa
+27,5.0,3.4,1.6,0.4,Iris-setosa
+28,5.2,3.5,1.5,0.2,Iris-setosa
+29,5.2,3.4,1.4,0.2,Iris-setosa
+30,4.7,3.2,1.6,0.2,Iris-setosa
+31,4.8,3.1,1.6,0.2,Iris-setosa
+32,5.4,3.4,1.5,0.4,Iris-setosa
+33,5.2,4.1,1.5,0.1,Iris-setosa
+34,5.5,4.2,1.4,0.2,Iris-setosa
+35,4.9,3.1,1.5,0.1,Iris-setosa
+36,5.0,3.2,1.2,0.2,Iris-setosa
+37,5.5,3.5,1.3,0.2,Iris-setosa
+38,4.9,3.1,1.5,0.1,Iris-setosa
+39,4.4,3.0,1.3,0.2,Iris-setosa
+40,5.1,3.4,1.5,0.2,Iris-setosa
+41,5.0,3.5,1.3,0.3,Iris-setosa
+42,4.5,2.3,1.3,0.3,Iris-setosa
+43,4.4,3.2,1.3,0.2,Iris-setosa
+44,5.0,3.5,1.6,0.6,Iris-setosa
+45,5.1,3.8,1.9,0.4,Iris-setosa
+46,4.8,3.0,1.4,0.3,Iris-setosa
+47,5.1,3.8,1.6,0.2,Iris-setosa
+48,4.6,3.2,1.4,0.2,Iris-setosa
+49,5.3,3.7,1.5,0.2,Iris-setosa
+50,5.0,3.3,1.4,0.2,Iris-setosa
+51,7.0,3.2,4.7,1.4,Iris-versicolor
+52,6.4,3.2,4.5,1.5,Iris-versicolor
+53,6.9,3.1,4.9,1.5,Iris-versicolor
+54,5.5,2.3,4.0,1.3,Iris-versicolor
+55,6.5,2.8,4.6,1.5,Iris-versicolor
+56,5.7,2.8,4.5,1.3,Iris-versicolor
+57,6.3,3.3,4.7,1.6,Iris-versicolor
+58,4.9,2.4,3.3,1.0,Iris-versicolor
+59,6.6,2.9,4.6,1.3,Iris-versicolor
+60,5.2,2.7,3.9,1.4,Iris-versicolor
+61,5.0,2.0,3.5,1.0,Iris-versicolor
+62,5.9,3.0,4.2,1.5,Iris-versicolor
+63,6.0,2.2,4.0,1.0,Iris-versicolor
+64,6.1,2.9,4.7,1.4,Iris-versicolor
+65,5.6,2.9,3.6,1.3,Iris-versicolor
+66,6.7,3.1,4.4,1.4,Iris-versicolor
+67,5.6,3.0,4.5,1.5,Iris-versicolor
+68,5.8,2.7,4.1,1.0,Iris-versicolor
+69,6.2,2.2,4.5,1.5,Iris-versicolor
+70,5.6,2.5,3.9,1.1,Iris-versicolor
+71,5.9,3.2,4.8,1.8,Iris-versicolor
+72,6.1,2.8,4.0,1.3,Iris-versicolor
+73,6.3,2.5,4.9,1.5,Iris-versicolor
+74,6.1,2.8,4.7,1.2,Iris-versicolor
+75,6.4,2.9,4.3,1.3,Iris-versicolor
+76,6.6,3.0,4.4,1.4,Iris-versicolor
+77,6.8,2.8,4.8,1.4,Iris-versicolor
+78,6.7,3.0,5.0,1.7,Iris-versicolor
+79,6.0,2.9,4.5,1.5,Iris-versicolor
+80,5.7,2.6,3.5,1.0,Iris-versicolor
+81,5.5,2.4,3.8,1.1,Iris-versicolor
+82,5.5,2.4,3.7,1.0,Iris-versicolor
+83,5.8,2.7,3.9,1.2,Iris-versicolor
+84,6.0,2.7,5.1,1.6,Iris-versicolor
+85,5.4,3.0,4.5,1.5,Iris-versicolor
+86,6.0,3.4,4.5,1.6,Iris-versicolor
+87,6.7,3.1,4.7,1.5,Iris-versicolor
+88,6.3,2.3,4.4,1.3,Iris-versicolor
+89,5.6,3.0,4.1,1.3,Iris-versicolor
+90,5.5,2.5,4.0,1.3,Iris-versicolor
+91,5.5,2.6,4.4,1.2,Iris-versicolor
+92,6.1,3.0,4.6,1.4,Iris-versicolor
+93,5.8,2.6,4.0,1.2,Iris-versicolor
+94,5.0,2.3,3.3,1.0,Iris-versicolor
+95,5.6,2.7,4.2,1.3,Iris-versicolor
+96,5.7,3.0,4.2,1.2,Iris-versicolor
+97,5.7,2.9,4.2,1.3,Iris-versicolor
+98,6.2,2.9,4.3,1.3,Iris-versicolor
+99,5.1,2.5,3.0,1.1,Iris-versicolor
+100,5.7,2.8,4.1,1.3,Iris-versicolor
+101,6.3,3.3,6.0,2.5,Iris-virginica
+102,5.8,2.7,5.1,1.9,Iris-virginica
+103,7.1,3.0,5.9,2.1,Iris-virginica
+104,6.3,2.9,5.6,1.8,Iris-virginica
+105,6.5,3.0,5.8,2.2,Iris-virginica
+106,7.6,3.0,6.6,2.1,Iris-virginica
+107,4.9,2.5,4.5,1.7,Iris-virginica
+108,7.3,2.9,6.3,1.8,Iris-virginica
+109,6.7,2.5,5.8,1.8,Iris-virginica
+110,7.2,3.6,6.1,2.5,Iris-virginica
+111,6.5,3.2,5.1,2.0,Iris-virginica
+112,6.4,2.7,5.3,1.9,Iris-virginica
+113,6.8,3.0,5.5,2.1,Iris-virginica
+114,5.7,2.5,5.0,2.0,Iris-virginica
+115,5.8,2.8,5.1,2.4,Iris-virginica
+116,6.4,3.2,5.3,2.3,Iris-virginica
+117,6.5,3.0,5.5,1.8,Iris-virginica
+118,7.7,3.8,6.7,2.2,Iris-virginica
+119,7.7,2.6,6.9,2.3,Iris-virginica
+120,6.0,2.2,5.0,1.5,Iris-virginica
+121,6.9,3.2,5.7,2.3,Iris-virginica
+122,5.6,2.8,4.9,2.0,Iris-virginica
+123,7.7,2.8,6.7,2.0,Iris-virginica
+124,6.3,2.7,4.9,1.8,Iris-virginica
+125,6.7,3.3,5.7,2.1,Iris-virginica
+126,7.2,3.2,6.0,1.8,Iris-virginica
+127,6.2,2.8,4.8,1.8,Iris-virginica
+128,6.1,3.0,4.9,1.8,Iris-virginica
+129,6.4,2.8,5.6,2.1,Iris-virginica
+130,7.2,3.0,5.8,1.6,Iris-virginica
+131,7.4,2.8,6.1,1.9,Iris-virginica
+132,7.9,3.8,6.4,2.0,Iris-virginica
+133,6.4,2.8,5.6,2.2,Iris-virginica
+134,6.3,2.8,5.1,1.5,Iris-virginica
+135,6.1,2.6,5.6,1.4,Iris-virginica
+136,7.7,3.0,6.1,2.3,Iris-virginica
+137,6.3,3.4,5.6,2.4,Iris-virginica
+138,6.4,3.1,5.5,1.8,Iris-virginica
+139,6.0,3.0,4.8,1.8,Iris-virginica
+140,6.9,3.1,5.4,2.1,Iris-virginica
+141,6.7,3.1,5.6,2.4,Iris-virginica
+142,6.9,3.1,5.1,2.3,Iris-virginica
+143,5.8,2.7,5.1,1.9,Iris-virginica
+144,6.8,3.2,5.9,2.3,Iris-virginica
+145,6.7,3.3,5.7,2.5,Iris-virginica
+146,6.7,3.0,5.2,2.3,Iris-virginica
+147,6.3,2.5,5.0,1.9,Iris-virginica
+148,6.5,3.0,5.2,2.0,Iris-virginica
+149,6.2,3.4,5.4,2.3,Iris-virginica
+150,5.9,3.0,5.1,1.8,Iris-virginica
diff --git a/src/__pycache__/decisionTreeVisuals.cpython-38.pyc b/src/__pycache__/decisionTreeVisuals.cpython-38.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f391a15126f2e62be4b28e315c6928ac274bef1d
Binary files /dev/null and b/src/__pycache__/decisionTreeVisuals.cpython-38.pyc differ
diff --git a/src/config.py b/src/config.py
index d31dec3e3e335b5b9974d3e9c9065281a0657bff..03afb9e9b7ffea2f48a6a2727940b8c6d8babf52 100644
--- a/src/config.py
+++ b/src/config.py
@@ -1,11 +1,15 @@
"""
This is a docstring for config.
"""
-from bokeh.models import Select, Slider, Row, Column
+from bokeh.models import Select, Slider, Row, Column, Dropdown, Paragraph
from bokeh.layouts import column, row
-x = 0
-y = 0
+
+
+X_train = 0
+X_test = 0
+y_train = 0
+y_test = 0
spectral = 0
source = 0
@@ -18,6 +22,32 @@ datasets_names = [
"Noisy Circles"
]
+model_names = [
+ "Logistic Regression",
+ "Decision Tree"
+]
+
+regularization_names = [
+ "none",
+ "l2",
+ "l1",
+ "elasticnet" #both l1 and l2 combined
+]
+
+regularization_names_liblinear = [
+ "l2",
+ "l1"
+]
+
+solver_names = [
+ "newton-cg", #dependent on l2 or none regularization
+ "lbfgs", #dependent on l1 or none regularization
+ "liblinear", #dependent on l1 or l2 regularization
+ "sag", #dependent on l2 or none regularization
+ "saga" #dependent on elasticnet, l1, l2, or none regularization
+]
+
+#synthetic data sliders and dropdowns
dataset_select = Select(value='Make Classification',
title='Select Dataset',
width=200,
@@ -51,6 +81,49 @@ inf_slider = Slider(title='Informative Classes',
step=1,
width=400)
+data_split_slider = Slider(title="Validation Size",
+ value=.2,
+ start=0.1,
+ end=.8,
+ step=.1,
+ width=400)
+
+# modelling sliders and dropdowns
+models_select = Select(value='Logistic Regression',
+ title='Select Model',
+ width=200,
+ options=model_names)
+
+normalization_select = Select(value='none',
+ title='Select Regularization',
+ width=200,
+ options=regularization_names)
+
+normalization_select_liblinear = Select(value='none',
+ title='Select Regularization',
+ width=200,
+ options=regularization_names_liblinear)
+
+solver_select = Select(value = "newton-cg",
+ title='Select Solver',
+ width=200,
+ options=solver_names)
+
+index_slider = Slider(title="Data Record",
+ value=9.0,
+ start=0,
+ end=3000.0,
+ step=1,
+ width=200)
+
+myMessage = 'You have entered nothing yet: (none)'
+text_output = Paragraph(text=myMessage, width=200, height=100)
selects = Row(dataset_select, width=420)
-inputs = Column(selects, samples_slider, classes_slider, inf_slider, features_slider)
+inputs = Column(selects,
+ samples_slider,
+ classes_slider,
+ inf_slider,
+ features_slider,
+ data_split_slider, models_select, solver_select, normalization_select, normalization_select_liblinear, index_slider)
+
\ No newline at end of file
diff --git a/src/data_vis.py b/src/data_vis.py
index c8ac781b3bd487e35c6eaf53f2633e307d45e62a..62c33a1f573d1d4d6c0b4222b2b5f2ed3544888d 100644
--- a/src/data_vis.py
+++ b/src/data_vis.py
@@ -1,9 +1,25 @@
"""
This is a docstrings for datavis
"""
-from bokeh.models import ColumnDataSource, Select, Slider, Plot, Scatter, Row, Column
+from bokeh.models import Scatter
from bokeh.plotting import figure
import config as config
+import pandas as pd
+from sklearn.tree import DecisionTreeClassifier
+from sklearn.linear_model import LogisticRegression
+# import numpy as np
+# import math
+# import matplotlib.pyplot as plt
+# import seaborn as sns
+
+# sklearn ML libraries/modules
+# from sklearn.metrics import accuracy_score
+# from sklearn.model_selection import train_test_split
+
+# lime modules
+import lime
+from lime.lime_tabular import LimeTabularExplainer
+# from lime import submodular_pick
def vis_synthetic():
"""This is a docstring for datavis
@@ -18,4 +34,102 @@ def vis_synthetic():
b.add_glyph(config.source, glyph)
- return b
\ No newline at end of file
+ return b
+
+
+def logisticRegressionmodel(X_train, X_test, Y_train, Y_test, record_value):
+ """This is a docstring for logisticRegressionVisuals
+
+ Returns:
+ _type_: _description_
+ """
+
+ # instantiating model
+ model_logreg = LogisticRegression(random_state=7)
+
+ # fit model on training set
+ model_logreg.fit(X_train, Y_train)
+
+ # grabbing unique class names
+ class_names=model_logreg.classes_
+
+ # grabbing specific row for model to use to make prediction
+ #ex_specie = X_test[3, ]
+
+ # lime_tabular is a module that contains functions that explain classifiers which use tabular data (matrices).
+ # LimeTabularExplainer is a function that explains predictions of tabular (matrix) data.
+
+ explainer = lime.lime_tabular.LimeTabularExplainer(X_train, feature_names=Y_train,
+ class_names=class_names, discretize_continuous=True)
+
+ # grab count of columns from feature matrix
+ featureCount = len(X_train)
+
+ # explain_instance is a function that generates explanations for a prediction after using LimeTabularExplainer.
+ exp = explainer.explain_instance(X_test[record_value],model_logreg.predict_proba,num_features=featureCount)
+
+ # converting explainations as list
+ tupleTest = exp.as_list()
+
+ # converting tuples to list
+ NewList = [list(x) for x in tupleTest]
+
+ # separating comparisons from feature scores
+ Labels1 = [item[0] for item in NewList]
+
+ # separating feature scores from comparisons
+ featureNums = [item[1] for item in NewList]
+
+
+ p = figure(x_range = Labels1, plot_height = 400, title = "Feature Importance Scores")
+ p.vbar(x = Labels1, top = featureNums, width = 0.5, color = "#fc8d59")
+
+ return p
+
+
+def decisionTreemodel(X_train, X_test, Y_train, Y_test, record_value):
+ """This is a docstring for decisionTreeVisuals
+
+ Returns:
+ _type_: _description_
+ """
+
+ # instantiating model
+ model_logreg = DecisionTreeClassifier(max_depth=8, random_state=0)
+
+ # fit model on training set
+ model_logreg.fit(X_train, Y_train)
+
+ # grabbing unique class names
+ class_names=model_logreg.classes_
+
+
+ # lime_tabular is a module that contains functions that explain classifiers which use tabular data (matrices).
+ # LimeTabularExplainer is a function that explains predictions of tabular (matrix) data.
+
+ explainer = lime.lime_tabular.LimeTabularExplainer(X_train, feature_names=Y_train,
+ class_names=class_names, discretize_continuous=True)
+
+ # grab count of columns from feature matrix
+ featureCount = len(X_train)
+
+ # explain_instance is a function that generates explanations for a prediction after using LimeTabularExplainer.
+ exp = explainer.explain_instance(X_test[record_value],model_logreg.predict_proba,num_features=featureCount)
+
+ # converting explainations as list
+ tupleTest = exp.as_list()
+
+ # converting tuples to list
+ NewList = [list(x) for x in tupleTest]
+
+ # separating comparisons from feature scores
+ Labels1 = [item[0] for item in NewList]
+
+ # separating feature scores from comparisons
+ featureNums = [item[1] for item in NewList]
+
+
+ p = figure(x_range = Labels1, plot_height = 400, title = "Feature Importance Scores")
+ p.vbar(x = Labels1, top = featureNums, width = 0.5, color = "#fc8d59")
+
+ return p
diff --git a/src/modelling.py b/src/modelling.py
new file mode 100644
index 0000000000000000000000000000000000000000..72f999ac1aeb41c12c9c6ab8f19a7867c26663aa
--- /dev/null
+++ b/src/modelling.py
@@ -0,0 +1,104 @@
+"""
+This is a docstrings for decisionTreeVisuals
+"""
+import config as config
+import pandas as pd
+from data_vis import vis_synthetic
+from synthetic import *
+
+
+# sklearn ML libraries/modules
+# from sklearn import preprocessing
+from sklearn.tree import DecisionTreeClassifier
+from sklearn.linear_model import LogisticRegression
+# from sklearn.metrics import accuracy_score
+from sklearn.model_selection import train_test_split
+from synthetic import update_samples_or_dataset
+from bokeh.models import Select, Slider, Row, Column
+from data_vis import decisionTreemodel, logisticRegressionmodel
+from bokeh.io import curdoc
+
+
+# lime modules
+from lime import submodular_pick
+import lime
+from lime.lime_tabular import LimeTabularExplainer
+from lime import submodular_pick
+
+import config as config
+from bokeh.plotting import figure
+
+
+class Models:
+ def __init__(self,
+ model='Logistic Regression',
+ penalty = 'none',
+ solver = 'newton-cg'):
+ self.model = model,
+ self.penalty = penalty,
+ self.solver = solver
+
+ def generate_algorithm(self):
+
+ if self.model == "Logistic Regression":
+ return LogisticRegression(penalty=self.penalty,
+ solver=self.solver
+ )
+ elif self.model == "Decision Tree":
+ return DecisionTreeClassifier()
+
+
+def model_callback(attrname, old, new):
+ """Callback function that updates models with appropriate data and updates on
+ slider/selector changes.
+
+ Args:
+ attrname (_type_): _description_
+ old (_type_): _description_
+ new (_type_): _description_
+ """
+
+
+ if config.models_select.value == "Logistic Regression" and (config.solver_select.value == "newton-cg" or config.solver_select.value == "sag" or config.solver_select.value == "lbfgs") and (config.dataset_select.value == 'Noisy Circles' or config.dataset_select.value == 'Noisy Moons'):
+
+ inputs = Column(config.selects, config.samples_slider, config.data_split_slider, config.models_select, config.solver_select, config.normalization_select, config.index_slider)
+ s = int(config.index_slider.value)
+ testModel = logisticRegressionmodel( config.X_train, config.X_test, config.y_train, config.y_test, s)
+ normalization_selected = "l2"
+ config.normalization_select.value = normalization_selected
+ b = vis_synthetic()
+
+ curdoc().clear()
+ curdoc().add_root(Row(inputs, b, testModel))
+
+
+ elif config.models_select.value == "Decision Tree" and (config.dataset_select.value == "Make Classification" or config.dataset_select.value == "Blobs" or config.dataset_select.value == 'Noisy Circles' or config.dataset_select.value == 'Noisy Moons'):
+ s = int(config.index_slider.value)
+ inputs = Column(config.selects, config.samples_slider, config.data_split_slider, config.models_select, config.solver_select, config.normalization_select, config.index_slider)
+ testModel = decisionTreemodel(config.X_train, config.X_test, config.y_train, config.y_test, s)
+ b = vis_synthetic()
+
+ curdoc().clear()
+ curdoc().add_root(Row(inputs, b, testModel))
+
+ elif config.models_select.value == "Logistic Regression" and (config.solver_select.value == "liblinear") and (config.dataset_select.value == 'Noisy Circles' or config.dataset_select.value == 'Noisy Moons'):
+ s = int(config.index_slider.value)
+ inputs = Column(config.selects, config.samples_slider, config.data_split_slider, config.models_select, config.solver_select, config.normalization_select_liblinear, config.index_slider)
+ testModel = logisticRegressionmodel(config.X_train, config.X_test, config.y_train, config.y_test, s)
+ b = vis_synthetic()
+
+ curdoc().clear()
+ curdoc().add_root(Row(inputs, b, testModel))
+
+
+config.models_select.on_change('value', model_callback)
+
+config.dataset_select.on_change('value', model_callback)
+
+config.solver_select.on_change('value', model_callback)
+
+config.normalization_select.on_change('value', model_callback)
+
+config.index_slider.on_change('value', model_callback)
+
+
diff --git a/src/synthetic.py b/src/synthetic.py
index 36b03f4fafbb10ff92e082aaf93834ab98df99b4..f2a57ce73822731f085f0e47d65df5b04620bc37 100644
--- a/src/synthetic.py
+++ b/src/synthetic.py
@@ -4,6 +4,7 @@ Synthetic data generation class, with callbacks and visualizations
import numpy as np
from sklearn import datasets
+from sklearn.model_selection import train_test_split
from bokeh.models import Select, Slider, Row, Column
from bokeh.io import curdoc
from bokeh.layouts import column, row
@@ -11,6 +12,7 @@ import math
from bokeh.palettes import Spectral6
import config as config
from data_vis import vis_synthetic
+# from modelling import *
class SyntheticData:
"""Class for creating a synthetic data object with default parameters.
@@ -20,12 +22,16 @@ class SyntheticData:
n_samples=1500,
n_features=4,
n_classes=3,
- n_inf=2):
+ n_inf=2,
+ test_size=.2,
+ shuffle=True):
self.dataset = dataset
self.n_samples = n_samples
self.n_features = n_features
self.n_classes = n_classes
self.n_inf = n_inf
+ self.test_size = test_size
+ self.shuffle=shuffle
def generator(self):
@@ -40,43 +46,79 @@ class SyntheticData:
"""
if self.dataset == 'Blobs':
#sliders: samples, classes, features
- return datasets.make_blobs(n_samples=self.n_samples,
- centers=self.n_classes,
- n_features=self.n_features,
- random_state=8
- )
+
+ x, y = datasets.make_blobs(n_samples=self.n_samples,
+ centers=self.n_classes,
+ n_features=self.n_features,
+ random_state=8
+ )
+
+ X_train, X_test, y_train, y_test = train_test_split(x,
+ y,
+ test_size=self.test_size,
+ shuffle=self.shuffle
+ )
+ return X_train, X_test, y_train, y_test
elif self.dataset == 'Make Classification':
#sliders: samples, features, informative features, classes
- return datasets.make_classification(n_samples=self.n_samples,
- n_features=self.n_features,
- n_informative=self.n_inf,
- n_redundant=0,
- n_clusters_per_class=1,
- n_classes=self.n_classes,
- random_state=8
- )
+ x, y = datasets.make_classification(n_samples=self.n_samples,
+ n_features=self.n_features,
+ n_informative=self.n_inf,
+ n_redundant=0,
+ n_clusters_per_class=1,
+ n_classes=self.n_classes,
+ random_state=8
+ )
+ print("Test size in generator",self.test_size)
+ X_train, X_test, y_train, y_test = train_test_split(x,
+ y,
+ test_size=self.test_size,
+ shuffle=self.shuffle
+ )
+ return X_train, X_test, y_train, y_test
elif self.dataset == 'Noisy Circles':
#sliders: samples
- return datasets.make_circles(n_samples=self.n_samples,
- factor=0.5,
- noise=0.05
+ x, y = datasets.make_circles(n_samples=self.n_samples,
+ factor=0.5,
+ noise=0.05
)
+
+ X_train, X_test, y_train, y_test = train_test_split(x,
+ y,
+ test_size=self.test_size,
+ shuffle=self.shuffle
+ )
+ return X_train, X_test, y_train, y_test
elif self.dataset == 'Noisy Moons':
#sliders: samples
- return datasets.make_moons(n_samples=self.n_samples,
- noise=0.05
- )
+ x, y = datasets.make_moons(n_samples=self.n_samples,
+ noise=0.05
+ )
+
+ X_train, X_test, y_train, y_test = train_test_split(x,
+ y,
+ test_size=self.test_size,
+ shuffle=self.shuffle
+ )
+ return X_train, X_test, y_train, y_test
elif self.dataset == 'Multilabel Classification':
#sliders: samples, features, classes
- return datasets.make_multilabel_classification(n_samples=self.n_samples,
- n_features=self.n_features,
- n_classes=self.n_classes,
- random_state=8
- )
+ x, y = datasets.make_multilabel_classification(n_samples=self.n_samples,
+ n_features=self.n_features,
+ n_classes=self.n_classes,
+ random_state=8
+ )
+
+ X_train, X_test, y_train, y_test = train_test_split(x,
+ y,
+ test_size=self.test_size,
+ shuffle=self.shuffle
+ )
+ return X_train, X_test, y_train, y_test
elif self.dataset == "No Structure":
return np.random.rand(self.n_samples, 2), None
@@ -95,12 +137,13 @@ def update_samples_or_dataset(attrname, old, new):
n_samples = int(config.samples_slider.value)
n_classes = int(config.classes_slider.value)
n_features = int(config.features_slider.value)
+ test_size = config.data_split_slider.value
- data = SyntheticData(dataset, n_samples, n_features, n_classes)
- config.x, config.y = data.generator()
- colors = [config.spectral[i] for i in config.y]
+ data = SyntheticData(dataset, n_samples, n_features, n_classes, test_size=test_size)
+ config.X_train, config.X_test, config.y_train, config.y_test = data.generator()
+ colors = [config.spectral[i] for i in config.y_train]
- config.source.data = dict(colors=colors, x=config.x[:, 0], y=config.x[:, 1])
+ config.source.data = dict(colors=colors, x=config.X_train[:, 0], y=config.X_train[:, 1])
elif config.dataset_select.value == 'Make Classification':
dataset = config.dataset_select.value
@@ -108,7 +151,8 @@ def update_samples_or_dataset(attrname, old, new):
n_classes = int(config.classes_slider.value)
n_features = int(config.features_slider.value)
n_inf = int(config.inf_slider.value)
-
+ test_size = config.data_split_slider.value
+ print("test size in callback", test_size)
if n_inf > n_features:
n_features = n_inf
config.features_slider.update(value=n_inf)
@@ -119,45 +163,47 @@ def update_samples_or_dataset(attrname, old, new):
config.inf_slider.update(value=n_inf)
config.features_slider.update(value=n_features)
- data = SyntheticData(dataset, n_samples, n_features, n_classes, n_inf)
- config.x, config.y = data.generator()
- colors = [config.spectral[i] for i in config.y]
+ data = SyntheticData(dataset, n_samples, n_features, n_classes, n_inf, test_size=test_size)
+ config.X_train, config.X_test, config.y_train, config.y_test = data.generator()
+ colors = [config.spectral[i] for i in config.y_train]
- config.source.data = dict(colors=colors, x=config.x[:, 0], y=config.x[:, 1])
+ config.source.data = dict(colors=colors, x=config.X_train[:, 0], y=config.X_train[:, 1])
elif config.dataset_select.value == 'Noisy Circles':
dataset = config.dataset_select.value
n_samples = int(config.samples_slider.value)
+ test_size = config.data_split_slider.value
- data = SyntheticData(dataset, n_samples)
- config.x, config.y = data.generator()
- colors = [config.spectral[i] for i in config.y]
+ data = SyntheticData(dataset, n_samples, test_size=test_size)
+ config.X_train, config.X_test, config.y_train, config.y_test = data.generator()
+ colors = [config.spectral[i] for i in config.y_train]
- config.source.data = dict(colors=colors, x=config.x[:, 0], y=config.x[:, 1])
+ config.source.data = dict(colors=colors, x=config.X_train[:, 0], y=config.X_train[:, 1])
elif config.dataset_select.value == 'Noisy Moons':
dataset = config.dataset_select.value
n_samples = int(config.samples_slider.value)
+ test_size = config.data_split_slider.value
- data = SyntheticData(dataset, n_samples)
- config.x, config.y = data.generator()
- colors = [config.spectral[i] for i in config.y]
+ data = SyntheticData(dataset, n_samples, test_size=test_size)
+ config.X_train, config.X_test, config.y_train, config.y_test = data.generator()
+ colors = [config.spectral[i] for i in config.y_train]
- config.source.data = dict(colors=colors, x=config.x[:, 0], y=config.x[:, 1])
+ config.source.data = dict(colors=colors, x=config.X_train[:, 0], y=config.X_train[:, 1])
elif config.dataset_select.value == 'Multilabel Classification':
dataset = config.dataset_select.value
n_samples = int(config.samples_slider.value)
n_features = int(config.features_slider.value)
n_classes = int(config.classes_slider.value)
+ test_size = config.data_split_slider.value
- data = SyntheticData(dataset, n_samples, n_features, n_classes)
- config.x, config.y = data.generator()
- colors = [config.spectral[i] for i in config.y]
+ data = SyntheticData(dataset, n_samples, n_features, n_classes, test_size=test_size)
+ config.X_train, config.X_test, config.y_train, config.y_test = data.generator()
+ colors = [config.spectral[i] for i in config.y_train]
- config.source.data = dict(colors=colors, x=config.x[:, 0], y=config.x[:, 1])
+ config.source.data = dict(colors=colors, x=config.X_train[:, 0], y=config.X_train[:, 1])
-
def update_layout(attrname, old, new):
"""Callback function that updates the sliders layout as datasets change.
@@ -167,27 +213,56 @@ def update_layout(attrname, old, new):
new (_type_): _description_
"""
if config.dataset_select.value == 'Blobs' or config.dataset_select.value == 'Multilabel Classification':
- inputs = Column(config.selects, config.samples_slider, config.classes_slider, config.features_slider)
+ inputs = Column(config.selects, config.samples_slider, config.classes_slider, config.features_slider, config.data_split_slider, config.models_select, config.solver_select, config.normalization_select, config.index_slider)
b = vis_synthetic()
+
curdoc().clear()
curdoc().add_root(Row(inputs, b))
elif config.dataset_select.value == 'Make Classification':
- inputs = Column(config.selects, config.samples_slider, config.classes_slider, config.features_slider, config.inf_slider)
+ inputs = Column(config.selects, config.samples_slider, config.classes_slider, config.features_slider, config.inf_slider, config.data_split_slider, config.models_select, config.solver_select, config.normalization_select, config.index_slider)
b = vis_synthetic()
+
curdoc().clear()
curdoc().add_root(Row(inputs, b))
elif config.dataset_select.value == 'Noisy Circles' or config.dataset_select.value == 'Noisy Moons':
- inputs = Column(config.selects, config.samples_slider)
+ inputs = Column(config.selects, config.samples_slider, config.data_split_slider, config.models_select, config.solver_select, config.normalization_select, config.index_slider)
b = vis_synthetic()
+
curdoc().clear()
curdoc().add_root(Row(inputs,b))
+ elif (config.dataset_select.value == 'Noisy Circles' or config.dataset_select.value == 'Noisy Moons') and (config.solver_select.value == "liblinear"):
+ inputs = Column(config.selects, config.samples_slider, config.data_split_slider, config.models_select, config.solver_select, config.normalization_select_liblinear, config.index_slider)
+ b = vis_synthetic()
+
+ curdoc().clear()
+ curdoc().add_root(Row(inputs,b))
+
+# def visualUpdate(attrname, old, new):
+# s = int(config.index_slider.value)
+# dataset = config.dataset_select.value
+# n_samples = int(config.samples_slider.value)
+# n_classes = int(config.classes_slider.value)
+# n_features = int(config.features_slider.value)
+# data = SyntheticData(dataset, n_samples, n_features, n_classes)
+# config.X_train, config.X_test, config.y_train, config.y_test = data.generator()
+# inputs = Column(config.index_slider)
+# # test = decisionTreemodel(config.x, config.y, s)
+# #p = figure(x_range = test[0], plot_height = 400, title = "Feature Importance Scores")
+# #p.vbar(x = test[0], top = test[1], width = 0.5, color = "#fc8d59")
+# curdoc().clear()
+# curdoc().add_root(Row(inputs))
+
+#data generator callbacks
config.dataset_select.on_change('value', update_samples_or_dataset)
config.samples_slider.on_change('value_throttled', update_samples_or_dataset)
config.classes_slider.on_change('value_throttled', update_samples_or_dataset)
config.features_slider.on_change('value', update_samples_or_dataset)
config.inf_slider.on_change('value', update_samples_or_dataset)
+#validation splits callbacks
+config.data_split_slider.on_change('value_throttled', update_samples_or_dataset)
+
config.dataset_select.on_change('value', update_layout)
\ No newline at end of file