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 &gt; 0.80","1 &gt; 0.68","2 &lt;= -1.38","-0.03 &lt; 1 &lt;= 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 &gt; 0.80","1 &gt; 0.68","2 &lt;= -1.38","-0.03 &lt; 1 &lt;= 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 &gt; 0.80","1 &gt; 0.68","2 &lt;= -1.38","-0.03 &lt; 1 &lt;= 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 &gt; 0.80","1 &gt; 0.68","2 &lt;= -1.38","-0.03 &lt; 1 &lt;= 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