commit 2b00bb382463038a184a858a4db7ca118942525f
parent 2db11f21757ae1d50f8bbbb16a1fc48de979d51d
Author: Andrew <andrewlaack1@gmail.com>
Date: Mon, 28 Oct 2024 15:58:28 -0500
Wrote basic code to do general decision tree related stuff.
Diffstat:
1 file changed, 463 insertions(+), 21 deletions(-)
diff --git a/decisionTreeClassifierFromScratch/DecisionTreeClassifier.ipynb b/decisionTreeClassifierFromScratch/DecisionTreeClassifier.ipynb
@@ -6,14 +6,14 @@
"source": [
"10.28 Stream:\n",
"\n",
- "1. Create some data\n",
- "2. Create method calculate gini impurity\n",
- "3. Create node class\n",
- "4. Create recursive splitting method\n",
+ "- [x] Create some data\n",
+ "- [x] Create method calculate gini impurity\n",
+ "- [x] Create node class\n",
+ "- [x] Create recursive splitting method\n",
+ "- [x] Print Tree\n",
"\n",
"LATER:\n",
"\n",
- "5. Print Tree\n",
"6. Create prediction method"
]
},
@@ -32,27 +32,55 @@
"| 2 | 20 | 1 |\n",
"| 3 | 15 | 1 |\n",
"| 3.2 | 20 | 1 |\n",
- "| 3.5 | 20 | 1 |"
+ "| 3.5 | 30 | 1 |"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "| Class | Count |\n",
+ "| - | - |\n",
+ "| 0 | 3 |\n",
+ "| 1 | 5 |\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "gini = 1 - sum(p^2 of each classification)\n",
+ "\n",
+ "5 + 3 = 8\n",
+ "\n",
+ "5 / 8 = .625\n",
+ "3 / 8 = .375\n",
+ "\n",
+ "1- prob(0)^2 + prob(1)^2\n",
+ "\n",
+ "1 - .375^2 + .625^2\n",
+ "= 0.46875"
]
},
{
"cell_type": "code",
- "execution_count": 26,
+ "execution_count": 140,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "<matplotlib.collections.PathCollection at 0x7fe6090860d0>"
+ "<matplotlib.collections.PathCollection at 0x7f037486e2d0>"
]
},
- "execution_count": 26,
+ "execution_count": 140,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
- "image/png": "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YIr4AAAApogPAABgivgAAACmiA8AAGCK+AAAAKaIDwAAYIr4AAAApogPAABgivgAAACmiA8AAGCK+AAAAKaIDwAAYIr4AAAApogPAABgivgAAACmiA8AAGCK+AAAAKaIDwAAYIr4AAAApogPAABgivgAAACmiA8AAGCK+AAAAKaIDwAAYIr4AAAApogPAABgivgAAACmiA8AAGCK+AAAAKaIDwAAYIr4AAAApogPAABgivgAAACmiA8AAGCK+AAAAKaIDwAAYIr4AAAApogPAABgivgAAACmiA8AAGCK+AAAAKaIDwAAYIr4AAAApogPAABgivgAAACmiA8AAGCK+AAAAKaIDwAAYIr4AAAApqKOj8rKSk2ePFlZWVnyeDwqLS1tsb6hoUGzZ89Wdna2evfureHDh+vhhx+O1bwAACDBRR0fjY2NGjlypIqLi1tdf/PNN+vll1/W0qVLtWnTJs2ZM0ezZ8/Wiy++eNTDAgCAxJcc7RUmTpyoiRMntrn+jTfeUGFhoQoKCiRJ119/vR555BG99dZbmjJlSqcHBQAAPUPM3/ORn5+vF198UZ988omccyorK9OHH36oSy+9tNXtQ6GQgsFgiwsAAOi5Yh4ff/jDHzR8+HBlZ2crNTVVl112mYqLizV27NhWty8qKpLf749ccnJyYj0SAADoRrokPtasWaMXX3xR1dXV+t3vfqdZs2bp1VdfbXX7efPmKRAIRC61tbWxHgkAAHQjUb/noz379+/XL3/5S5WUlGjSpEmSpDPPPFM1NTW65557NH78+MOu4/P55PP5YjkGAADoxmL6zEdTU5Oamprk9ba82aSkJIXD4VjeFQAASFBRP/PR0NCgLVu2RH7etm2bampq1L9/f+Xm5uqiiy7S3Llz1bt3bw0aNEgVFRV68sknde+998Z0cAAAkJg8zjkXzRXKy8s1bty4w5YXFhZqyZIlqq+v17x58/TKK6/os88+06BBg3T99dfrZz/7mTwezxFvPxgMyu/3KxAIKD09PZrRAABAnETz+B11fHQ14gMAgMQTzeM33+0CAABMER8AAMAU8QEAAEwRHwAAwBTxAQAATBEfAADAFPEBAABMER8AAMAU8QEAAEwRHwAAwBTxAQAATBEfAADAFPEBAABMER8AAMAU8QEAAEwRHwAAwBTxAQAATBEfAADAFPEBAABMER8AAMAU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UnT22Wdry5YtXTRdz5CamqpTTjlFknTuuedq7dq1euCBB/TII48cti3Hc+dFs5+/yupYPqZfdsnLy9PKlStbLFuxYkW7r40hNmpqajRw4MB4j9FtOec0e/ZslZSUaNWqVRo8ePARr8Px3Dmd2ddf1dzcrA0bNnBMRykcDisUCrW6juM5dtrbz19ldiybv8W1C+3du9etX7/erV+/3kly9957r1u/fr3bvn27c8652267zU2fPj2y/T//+U933HHHublz57pNmza54uJil5SU5F5++eV4/RMSQrT7+b777nOlpaXuH//4h9uwYYP76U9/6rxer3v11Vfj9U/o9n784x87v9/vysvL3c6dOyOXffv2RbaZPn26u+222yI/v/766y45Odndc889btOmTW7+/PkuJSXFbdiwIR7/hITRmX3961//2i1fvtxt3brVVVdXu6uvvtr16tXLvf/++/H4JySE2267zVVUVLht27a5d9991912223O4/G4V155xTnH8Rwr0e7neB3LPSo+Dn2k86uXwsJC55xzhYWF7qKLLjrsOmeddZZLTU11Q4YMcYsXLzafO9FEu58XLFjgvv71r7tevXq5/v37u4KCArdq1ar4DJ8gWtu/klocnxdddFFknx/y3HPPuVNPPdWlpqa6ESNGuJdeesl28ATUmX09Z84cl5ub61JTU11GRob79re/7datW2c/fAL5wQ9+4AYNGuRSU1PdiSee6C6++OLIA6JzHM+xEu1+jtex7HHOua59bgUAAODfjun3fAAAAHvEBwAAMEV8AAAAU8QHAAAwRXwAAABTxAcAADBFfAAAAFPEBwAAMEV8AAAAU8QHAAAwRXwAAABTxAcAADD1/wHMv4LAUmBRfAAAAABJRU5ErkJggg==",
+ "image/png": "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mRL47/79+2vAgAHq2bOn8vPzdcUVV5ywfV5enh555JHWHkOSFNepkypLSxtd77jdap+U1CaPDQBoXLvOnU+6jb+urlnbIfy0+XU+zj77bHXp0kWfNvIKQ25urrxeb+BWUlLSao898Kab5DTwastxpq5OA66/vtUeDwDQPJ3POUdJ/ftLTXyk1hUVpT6TJlmcCra0eXzs27dPBw8eVGpqaoPrY2NjlZCQUO/WWobec4/iOnZsMEAct1tpF1ygc773vVZ7PABA8ziOo5G//GWT2wx74AG155WPiBR0fFRWVqqoqEhFRUWSpD179qioqEh79+5VZWWlfvzjH2v9+vX67LPPtHr1ak2YMEG9evXS6NGjW3v2k4pPS9PN776rLr17SzoWHMcru9eYMbrhrbfkijpjrrMGAKeV744dq6v/+EfFdeok6d//j3bHxOiShx7SiP/5nxBPiLbimCAvdJGfn68RI0acsHzq1KmaN2+eJk6cqM2bN6uiokJpaWkaNWqUfv7znys5OblZ9+/z+eTxeOT1elvtVRBjjEref1///PBDuaKj1XPUKHXJymqV+wYAnJra6mr9Y/lyfbVnj9olJqrP97+vdomJoR4LQQrm+Tvo+GhrbREfAACgbQXz/M0flgMAAFYRHwAAwCriAwAAWEV8AAAAq4gPAABgFfEBAACsIj4AAIBVxAcAALCK+AAAAFYRHwAAwCriAwAAWEV8AAAAq4gPAABgFfEBAACsIj4AAIBVxAcAALCK+AAAAFYRHwAAwCriAwAAWEV8AAAAq4gPAABgFfEBAACsIj4AAIBVxAcAALCK+AAAAFYRHwAAwCriAwAAWEV8AAAAq4gPAABgFfEBAACsIj4AAIBVxAcAALAqKtQDAADObLW1fq1atUt79lQoMbGdxo37ruLjY0M9FtoQ8QEACJkVK/6h229frtLSSjmOZIzUvn20fvrT4XrwwWFyHCfUI6INEB8AgJBYvXq3JkxYImOMpGPhIUmHD9coN3e1amv9euih4SGcEG2Fcz4AACHxwAPvSPp3dHzbo4+u01dffW1xIthCfAAArNu586A2bSqV399IeUg6erROr7++3eJUsIX4AABY98UXh0+6jdvtatZ2CD/EBwDAuvT0hJNuU1vrV2amx8I0sI34AABYl5np0YgR35Hb3finWRISYjVxYm+LU8EW4gMAEBJP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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
@@ -68,12 +96,15 @@
"values = [\n",
" [1 , 10 , 0],\n",
" [2 , 10 , 0],\n",
- " [3 , 10 , 0],\n",
+ " [3 , 12 , 0],\n",
+ " [3 , 9 , 1],\n",
+ " [1 , 7 , 1],\n",
+ " [2 , 9 , 1],\n",
" [1 , 15 , 1],\n",
" [2 , 20 , 1],\n",
" [3 , 15 , 1],\n",
" [3.2 , 20 , 1],\n",
- " [3.5 , 20 , 1],\n",
+ " [3.5 , 30 , 1],\n",
"]\n",
"\n",
"values = np.array(values)\n",
@@ -83,26 +114,437 @@
},
{
"cell_type": "code",
- "execution_count": 27,
+ "execution_count": 141,
"metadata": {},
"outputs": [
{
"data": {
- "image/png": "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",
"text/plain": [
- "<Figure size 640x480 with 1 Axes>"
+ "array([[ 1. , 10. , 0. ],\n",
+ " [ 2. , 10. , 0. ],\n",
+ " [ 3. , 12. , 0. ],\n",
+ " [ 3. , 9. , 1. ],\n",
+ " [ 1. , 7. , 1. ],\n",
+ " [ 2. , 9. , 1. ],\n",
+ " [ 1. , 15. , 1. ],\n",
+ " [ 2. , 20. , 1. ],\n",
+ " [ 3. , 15. , 1. ],\n",
+ " [ 3.2, 20. , 1. ],\n",
+ " [ 3.5, 30. , 1. ]])"
]
},
+ "execution_count": 141,
"metadata": {},
- "output_type": "display_data"
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "values"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 142,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0.39669421487603307"
+ ]
+ },
+ "execution_count": 142,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# 1D list of classifications\n",
+ "# elements is a numpy array\n",
+ "# assume final element is label\n",
+ "\n",
+ "def giniImpurity(elements):\n",
+ "\n",
+ " counts = {}\n",
+ "\n",
+ " for i in elements:\n",
+ " try:\n",
+ " counts[i[-1]] = counts[i[-1]] + 1\n",
+ " except:\n",
+ " counts[i[-1]] = 1\n",
+ " \n",
+ " # 1. Iterate through all element of counts\n",
+ " # 2. for each of these calculate probability \n",
+ " # 3. add this to the sum\n",
+ " # 4. return sum\n",
+ "\n",
+ " sum = 0\n",
+ " for i in counts.keys():\n",
+ " # cur = instances of current class\n",
+ " cur = counts[i] \n",
+ " sum += (cur/len(elements)) ** 2\n",
+ " return 1 - sum\n",
+ "\n",
+ "\n",
+ "giniImpurity(values)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 143,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import graphviz\n",
+ "\n",
+ "class SplitNode:\n",
+ " def __init__(self, colNum=None, criteria=None, leftNode=None, rightNode=None):\n",
+ " self.colNum = colNum\n",
+ " self.criteria = criteria\n",
+ " self.leftNode = leftNode\n",
+ " self.rightNode = rightNode\n",
+ " \n",
+ " # Column number we are splitting on\n",
+ " colNum = None\n",
+ " # Value to split on (<=)\n",
+ " criteria = None\n",
+ "\n",
+ " # Iff leftNode = None and rightNode = None then leaf\n",
+ " leftNode = None\n",
+ " rightNode = None\n",
+ "\n",
+ " def __str__(self, ):\n",
+ " retStr = \"Split on: \" + str(self.colNum)\n",
+ " retStr += \" Split Value: <= \" + str(self.criteria)\n",
+ " retStr += \"\\n\"\n",
+ " if self.leftNode != None:\n",
+ " retStr += self.leftNode.__str__()\n",
+ " if self.rightNode != None:\n",
+ " retStr += self.rightNode.__str__()\n",
+ " return retStr\n",
+ " \n",
+ " def graph(self, columnNames=[]):\n",
+ "\n",
+ " diGraph = graphviz.Digraph()\n",
+ " helperGraph(\"0\",self, diGraph, columnNames)\n",
+ " return diGraph\n",
+ "\n",
+ "\n",
+ "# Recursive method to build visualization of tree\n",
+ "def helperGraph(prior, curNode, diGraph, columnNames):\n",
+ "\n",
+ " if curNode.colNum == None:\n",
+ " # Maybe add impurity stats later\n",
+ " diGraph.node(str(id(curNode)), f\"Leaf\")\n",
+ " if prior != \"0\":\n",
+ " diGraph.edge(prior, str(id(curNode)))\n",
+ " return\n",
+ "\n",
+ " splitOn = str(curNode.colNum)\n",
+ " if(len(columnNames) > curNode.colNum):\n",
+ " splitOn = columnNames[curNode.colNum]\n",
+ " \n",
+ " diGraph.node(str(id(curNode)), f\"Split on: {splitOn} \\n Split Value: <= {str(curNode.criteria)}\")\n",
+ " if curNode.leftNode != None:\n",
+ " helperGraph(str(id(curNode)), curNode.leftNode, diGraph, columnNames)\n",
+ "\n",
+ " if curNode.rightNode != None:\n",
+ " helperGraph(str(id(curNode)), curNode.rightNode, diGraph, columnNames)\n",
+ " \n",
+ " if prior != \"0\":\n",
+ " diGraph.edge(prior, str(id(curNode)))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Recursive find <= on left and > on right"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 144,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[ 1. , 10. , 0. ],\n",
+ " [ 2. , 10. , 0. ],\n",
+ " [ 3. , 12. , 0. ],\n",
+ " [ 3. , 9. , 1. ],\n",
+ " [ 1. , 7. , 1. ],\n",
+ " [ 2. , 9. , 1. ],\n",
+ " [ 1. , 15. , 1. ],\n",
+ " [ 2. , 20. , 1. ],\n",
+ " [ 3. , 15. , 1. ],\n",
+ " [ 3.2, 20. , 1. ],\n",
+ " [ 3.5, 30. , 1. ]])"
+ ]
+ },
+ "execution_count": 144,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "values"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 145,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def split(samples, criteria, column):\n",
+ " leftArr = []\n",
+ " rightArr = []\n",
+ "\n",
+ " for sample in samples:\n",
+ " if sample[column] <= criteria:\n",
+ " leftArr.append(sample)\n",
+ " else:\n",
+ " rightArr.append(sample)\n",
+ " \n",
+ " leftArr = np.array(leftArr)\n",
+ " rightArr = np.array(rightArr)\n",
+ " return leftArr, rightArr"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 146,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# take input of samples as matrix (np.array)\n",
+ "# return splitting node\n",
+ "def recurse(samples):\n",
+ "\n",
+ " if giniImpurity(samples) == 0:\n",
+ " return SplitNode()\n",
+ " \n",
+ " # Track best choice so far\n",
+ " bestGini = 1\n",
+ " colNum = 0\n",
+ " criteria = 0\n",
+ "\n",
+ " for i in range(len(samples)):\n",
+ " for x in range(0,len(samples[i])-1):\n",
+ "\n",
+ " # i = current row\n",
+ " # x = current column\n",
+ " \n",
+ " leftArr, rightArr = split(samples, samples[i][x], x)\n",
+ " gini = giniImpurity(leftArr)\n",
+ " gini += giniImpurity(rightArr)\n",
+ " if gini < bestGini:\n",
+ " bestGini = gini\n",
+ " colNum = x\n",
+ " criteria = samples[i][x]\n",
+ "\n",
+ " leftArr, rightArr = split(samples, criteria, colNum)\n",
+ " # colNum, criteria, leftNode, rightNode\n",
+ " splitNode = SplitNode(colNum, criteria, recurse(leftArr), recurse(rightArr))\n",
+ " return splitNode\n",
+ "\n",
+ "rootNode = recurse(values)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 147,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Split on: 1 Split Value: <= 7.0\n",
+ "Split on: None Split Value: <= None\n",
+ "Split on: 1 Split Value: <= 20.0\n",
+ "Split on: 0 Split Value: <= 3.0\n",
+ "Split on: 1 Split Value: <= 12.0\n",
+ "Split on: 1 Split Value: <= 9.0\n",
+ "Split on: None Split Value: <= None\n",
+ "Split on: None Split Value: <= None\n",
+ "Split on: None Split Value: <= None\n",
+ "Split on: None Split Value: <= None\n",
+ "Split on: None Split Value: <= None\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(rootNode)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 151,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/svg+xml": [
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
+ "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
+ " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
+ "<!-- Generated by graphviz version 2.43.0 (0)\n",
+ " -->\n",
+ "<!-- Title: %3 Pages: 1 -->\n",
+ "<svg width=\"481pt\" height=\"493pt\"\n",
+ " viewBox=\"0.00 0.00 480.81 492.70\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
+ "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 488.7)\">\n",
+ "<title>%3</title>\n",
+ "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-488.7 476.81,-488.7 476.81,4 -4,4\"/>\n",
+ "<!-- 139652816443280 -->\n",
+ "<g id=\"node1\" class=\"node\">\n",
+ "<title>139652816443280</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"270.72\" cy=\"-457.83\" rx=\"111.95\" ry=\"26.74\"/>\n",
+ "<text text-anchor=\"middle\" x=\"270.72\" y=\"-461.63\" font-family=\"Times,serif\" font-size=\"14.00\">Split on: y </text>\n",
+ "<text text-anchor=\"middle\" x=\"270.72\" y=\"-446.63\" font-family=\"Times,serif\" font-size=\"14.00\"> Split Value: <= 7.0</text>\n",
+ "</g>\n",
+ "<!-- 139652816327696 -->\n",
+ "<g id=\"node2\" class=\"node\">\n",
+ "<title>139652816327696</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"187.72\" cy=\"-368.09\" rx=\"30.59\" ry=\"18\"/>\n",
+ "<text text-anchor=\"middle\" x=\"187.72\" y=\"-364.39\" font-family=\"Times,serif\" font-size=\"14.00\">Leaf</text>\n",
+ "</g>\n",
+ "<!-- 139652816443280->139652816327696 -->\n",
+ "<g id=\"edge1\" class=\"edge\">\n",
+ "<title>139652816443280->139652816327696</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M246.72,-431.45C234.86,-418.91 220.66,-403.91 209.17,-391.76\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"211.47,-389.1 202.06,-384.24 206.39,-393.91 211.47,-389.1\"/>\n",
+ "</g>\n",
+ "<!-- 139652816446608 -->\n",
+ "<g id=\"node3\" class=\"node\">\n",
+ "<title>139652816446608</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"354.72\" cy=\"-368.09\" rx=\"118.17\" ry=\"26.74\"/>\n",
+ "<text text-anchor=\"middle\" x=\"354.72\" y=\"-371.89\" font-family=\"Times,serif\" font-size=\"14.00\">Split on: y </text>\n",
+ "<text text-anchor=\"middle\" x=\"354.72\" y=\"-356.89\" font-family=\"Times,serif\" font-size=\"14.00\"> Split Value: <= 20.0</text>\n",
+ "</g>\n",
+ "<!-- 139652816443280->139652816446608 -->\n",
+ "<g id=\"edge10\" class=\"edge\">\n",
+ "<title>139652816443280->139652816446608</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M295.02,-431.45C303.9,-422.18 314.07,-411.55 323.48,-401.73\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"326.09,-404.06 330.48,-394.41 321.04,-399.21 326.09,-404.06\"/>\n",
+ "</g>\n",
+ "<!-- 139652816443920 -->\n",
+ "<g id=\"node4\" class=\"node\">\n",
+ "<title>139652816443920</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"274.72\" cy=\"-278.35\" rx=\"111.95\" ry=\"26.74\"/>\n",
+ "<text text-anchor=\"middle\" x=\"274.72\" y=\"-282.15\" font-family=\"Times,serif\" font-size=\"14.00\">Split on: x </text>\n",
+ "<text text-anchor=\"middle\" x=\"274.72\" y=\"-267.15\" font-family=\"Times,serif\" font-size=\"14.00\"> Split Value: <= 3.0</text>\n",
+ "</g>\n",
+ "<!-- 139652816446608->139652816443920 -->\n",
+ "<g id=\"edge8\" class=\"edge\">\n",
+ "<title>139652816446608->139652816443920</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M331.58,-341.71C323.21,-332.53 313.63,-322.02 304.75,-312.28\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"307.13,-309.7 297.81,-304.67 301.96,-314.42 307.13,-309.7\"/>\n",
+ "</g>\n",
+ "<!-- 139652816442768 -->\n",
+ "<g id=\"node11\" class=\"node\">\n",
+ "<title>139652816442768</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"434.72\" cy=\"-278.35\" rx=\"30.59\" ry=\"18\"/>\n",
+ "<text text-anchor=\"middle\" x=\"434.72\" y=\"-274.65\" font-family=\"Times,serif\" font-size=\"14.00\">Leaf</text>\n",
+ "</g>\n",
+ "<!-- 139652816446608->139652816442768 -->\n",
+ "<g id=\"edge9\" class=\"edge\">\n",
+ "<title>139652816446608->139652816442768</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M377.86,-341.71C389.29,-329.17 402.98,-314.17 414.05,-302.02\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"416.76,-304.25 420.91,-294.5 411.58,-299.53 416.76,-304.25\"/>\n",
+ "</g>\n",
+ "<!-- 139652816449104 -->\n",
+ "<g id=\"node5\" class=\"node\">\n",
+ "<title>139652816449104</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"191.72\" cy=\"-188.61\" rx=\"118.17\" ry=\"26.74\"/>\n",
+ "<text text-anchor=\"middle\" x=\"191.72\" y=\"-192.41\" font-family=\"Times,serif\" font-size=\"14.00\">Split on: y </text>\n",
+ "<text text-anchor=\"middle\" x=\"191.72\" y=\"-177.41\" font-family=\"Times,serif\" font-size=\"14.00\"> Split Value: <= 12.0</text>\n",
+ "</g>\n",
+ "<!-- 139652816443920->139652816449104 -->\n",
+ "<g id=\"edge6\" class=\"edge\">\n",
+ "<title>139652816443920->139652816449104</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M250.72,-251.97C241.94,-242.7 231.89,-232.07 222.6,-222.25\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"225.09,-219.79 215.68,-214.93 220.01,-224.6 225.09,-219.79\"/>\n",
+ "</g>\n",
+ "<!-- 139652816441232 -->\n",
+ "<g id=\"node10\" class=\"node\">\n",
+ "<title>139652816441232</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"358.72\" cy=\"-188.61\" rx=\"30.59\" ry=\"18\"/>\n",
+ "<text text-anchor=\"middle\" x=\"358.72\" y=\"-184.91\" font-family=\"Times,serif\" font-size=\"14.00\">Leaf</text>\n",
+ "</g>\n",
+ "<!-- 139652816443920->139652816441232 -->\n",
+ "<g id=\"edge7\" class=\"edge\">\n",
+ "<title>139652816443920->139652816441232</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M299.02,-251.97C311.02,-239.43 325.39,-224.43 337.02,-212.28\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"339.83,-214.41 344.22,-204.76 334.77,-209.57 339.83,-214.41\"/>\n",
+ "</g>\n",
+ "<!-- 139652816329744 -->\n",
+ "<g id=\"node6\" class=\"node\">\n",
+ "<title>139652816329744</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"111.72\" cy=\"-98.87\" rx=\"111.95\" ry=\"26.74\"/>\n",
+ "<text text-anchor=\"middle\" x=\"111.72\" y=\"-102.67\" font-family=\"Times,serif\" font-size=\"14.00\">Split on: y </text>\n",
+ "<text text-anchor=\"middle\" x=\"111.72\" y=\"-87.67\" font-family=\"Times,serif\" font-size=\"14.00\"> Split Value: <= 9.0</text>\n",
+ "</g>\n",
+ "<!-- 139652816449104->139652816329744 -->\n",
+ "<g id=\"edge4\" class=\"edge\">\n",
+ "<title>139652816449104->139652816329744</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M168.58,-162.23C160.21,-153.05 150.63,-142.54 141.75,-132.8\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"144.13,-130.22 134.81,-125.19 138.96,-134.94 144.13,-130.22\"/>\n",
+ "</g>\n",
+ "<!-- 139652816451152 -->\n",
+ "<g id=\"node9\" class=\"node\">\n",
+ "<title>139652816451152</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"271.72\" cy=\"-98.87\" rx=\"30.59\" ry=\"18\"/>\n",
+ "<text text-anchor=\"middle\" x=\"271.72\" y=\"-95.17\" font-family=\"Times,serif\" font-size=\"14.00\">Leaf</text>\n",
+ "</g>\n",
+ "<!-- 139652816449104->139652816451152 -->\n",
+ "<g id=\"edge5\" class=\"edge\">\n",
+ "<title>139652816449104->139652816451152</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M214.86,-162.23C226.29,-149.69 239.98,-134.69 251.05,-122.54\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"253.76,-124.77 257.91,-115.02 248.58,-120.05 253.76,-124.77\"/>\n",
+ "</g>\n",
+ "<!-- 139652816308624 -->\n",
+ "<g id=\"node7\" class=\"node\">\n",
+ "<title>139652816308624</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"72.72\" cy=\"-18\" rx=\"30.59\" ry=\"18\"/>\n",
+ "<text text-anchor=\"middle\" x=\"72.72\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Leaf</text>\n",
+ "</g>\n",
+ "<!-- 139652816329744->139652816308624 -->\n",
+ "<g id=\"edge2\" class=\"edge\">\n",
+ "<title>139652816329744->139652816308624</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M98.95,-72.05C94.58,-63.2 89.69,-53.32 85.33,-44.5\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"88.43,-42.87 80.86,-35.46 82.16,-45.97 88.43,-42.87\"/>\n",
+ "</g>\n",
+ "<!-- 139652816384400 -->\n",
+ "<g id=\"node8\" class=\"node\">\n",
+ "<title>139652816384400</title>\n",
+ "<ellipse fill=\"none\" stroke=\"black\" cx=\"151.72\" cy=\"-18\" rx=\"30.59\" ry=\"18\"/>\n",
+ "<text text-anchor=\"middle\" x=\"151.72\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">Leaf</text>\n",
+ "</g>\n",
+ "<!-- 139652816329744->139652816384400 -->\n",
+ "<g id=\"edge3\" class=\"edge\">\n",
+ "<title>139652816329744->139652816384400</title>\n",
+ "<path fill=\"none\" stroke=\"black\" d=\"M124.82,-72.05C129.3,-63.2 134.32,-53.32 138.79,-44.5\"/>\n",
+ "<polygon fill=\"black\" stroke=\"black\" points=\"141.98,-45.96 143.38,-35.46 135.73,-42.79 141.98,-45.96\"/>\n",
+ "</g>\n",
+ "</g>\n",
+ "</svg>\n"
+ ],
+ "text/plain": [
+ "<graphviz.graphs.Digraph at 0x7f03746bb290>"
+ ]
+ },
+ "execution_count": 151,
+ "metadata": {},
+ "output_type": "execute_result"
}
],
"source": [
- "plt.scatter(x = values[:,0], y = values[:,1], c= values[:,2], cmap=\"jet\")\n",
- "plt.axhline(y=15, color='r')\n",
- "plt.fill_between(x=np.linspace(0, 3.5, 100), y1=0, y2=15, color='lightblue', alpha=0.3)\n",
- "plt.fill_between(x=np.linspace(0, 3.5, 100), y1=15, y2=20, color='red', alpha=0.1)\n",
- "plt.show()"
+ "rootNode.graph(columnNames=['x', 'y'])"
]
}
],