fuzzy-rules-generator/temp_density_regression.ipynb

941 lines
73 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>T</th>\n",
" <th>Al2O3</th>\n",
" <th>TiO2</th>\n",
" <th>Density</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>20</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.06250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>25</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.05979</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>35</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.05404</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>40</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.05103</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>45</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.04794</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" T Al2O3 TiO2 Density\n",
"0 20 0.0 0.0 1.06250\n",
"1 25 0.0 0.0 1.05979\n",
"2 35 0.0 0.0 1.05404\n",
"3 40 0.0 0.0 1.05103\n",
"4 45 0.0 0.0 1.04794"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>T</th>\n",
" <th>Al2O3</th>\n",
" <th>TiO2</th>\n",
" <th>Density</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>30</td>\n",
" <td>0.00</td>\n",
" <td>0.0</td>\n",
" <td>1.05696</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>55</td>\n",
" <td>0.00</td>\n",
" <td>0.0</td>\n",
" <td>1.04158</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>25</td>\n",
" <td>0.05</td>\n",
" <td>0.0</td>\n",
" <td>1.08438</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>30</td>\n",
" <td>0.05</td>\n",
" <td>0.0</td>\n",
" <td>1.08112</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>35</td>\n",
" <td>0.05</td>\n",
" <td>0.0</td>\n",
" <td>1.07781</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" T Al2O3 TiO2 Density\n",
"0 30 0.00 0.0 1.05696\n",
"1 55 0.00 0.0 1.04158\n",
"2 25 0.05 0.0 1.08438\n",
"3 30 0.05 0.0 1.08112\n",
"4 35 0.05 0.0 1.07781"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import pandas as pd\n",
"\n",
"train = pd.read_csv(\"data/density_train.csv\", sep=\";\", decimal=\",\")\n",
"test = pd.read_csv(\"data/density_test.csv\", sep=\";\", decimal=\",\")\n",
"\n",
"train[\"Density\"] = train[\"Density\"]\n",
"test[\"Density\"] = test[\"Density\"]\n",
"\n",
"display(train.head())\n",
"display(test.head())"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAzoAAANECAYAAAB4mVoFAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACC/klEQVR4nOzde3gU5d3/8c8GwoYICSDmBAGjIOcgB8HgAdQciJSSaqmiT0GK9hT8QVO1xooQ0xqqUrSVgodKqhJRrOChCFmjgQcJapBUQKViEdSSUFESksi6zc7vD59sWXPa3exmN5P367r20pm9Z+77O7OT2Q+zO2sxDMMQAAAAAJhIWLAHAAAAAAD+RtABAAAAYDoEHQAAAACmQ9ABAAAAYDoEHQAAAACmQ9ABAAAAYDoEHQAAAACmQ9ABAAAAYDoEHQAAAACmQ9ABAAAwMYvFomXLlgV7GECHI+gAXrJYLB49SktLgz1UAEAX8Kc//UkWi0WTJ0/2qP3bb7+thQsXatSoUTrjjDM0aNAg/eAHP9A//vGPZtsbhqEnn3xSl156qfr06aPIyEiNGTNGd999t+rq6pq0f/TRRzV16lTFxsbKarUqKSlJ8+fP18cff9yeMgGvWQzDMII9CKAzeeqpp9ymn3jiCdlsNj355JNu89PS0hQbG9uRQwMAdEEXXXSR/vWvf+njjz/Whx9+qCFDhrg9b7FYtHTpUtdVne9///t64403NHv2bCUnJ6uyslIPPfSQamtrtWvXLo0ePdq1bENDg6677jo9++yzuuSSS3TVVVcpMjJS//u//6uioiKNHDlSr776qtv57uc//7nq6+s1ZswY9e3bV4cOHdKjjz6qhoYG/f3vf1dCQkKHbBdABoB2yc7ONjiUAADB8M9//tOQZDz//PPGWWedZSxbtqxJG0nG0qVLXdNvvPGGYbfb3dr84x//MKxWq3H99de7zb/nnnsMScYtt9zSZL0vvviiERYWZkyfPr3NcZaXlxuSjIKCAg8rA9qPj64BAAB0UuvWrVPfvn01Y8YMff/739e6devaXGbKlCnq0aOH27yhQ4dq1KhRev/9913zvvrqK913330677zzVFBQ0GQ9M2fO1Lx587Rlyxbt2rWr1T7PPvtsSdKJEyfaLgrwE4IOAABAJ7Vu3TpdddVV6tGjh+bMmaMPP/xQb7/9ttfrMQxDVVVV6t+/v2vejh079OWXX+q6665T9+7dm11u7ty5kqSXX365yXPHjx/XsWPHVF5ervnz50uSrrjiCq/HBviKoAMAANAJ7d69Wx988IGuvfZaSdLFF1+sgQMHenRV59vWrVunzz77TNdcc41r3nvvvSdJGjt2bIvLNT53+pWgRgMGDFBsbKwuuOAC7dy5U3/4wx+Ulpbm9dgAXxF0AAAAOqF169YpNjZWl112maRvbjpwzTXXaP369WpoaPB4PR988IGys7OVkpKiefPmueafPHlSktS7d+8Wl218rqampslzr7zyijZv3qwVK1Zo0KBBzd6hDQik5q9DAgAAIGQ1NDRo/fr1uuyyy3To0CHX/MmTJ2vFihUqKSlRenp6m+uprKzUjBkzFB0dreeee07dunVzPdcYYhoDT3NaC0ONASwzM1OzZs3S6NGj1atXLy1cuNCzIoF24ooOAABAJ/Paa6/p6NGjWr9+vYYOHep6/OAHP5Akjz6+Vl1drczMTJ04cUJbtmxpctvnESNGSJLefffdFtfR+NzIkSNb7evcc8/VuHHjfPpYHeArrugAAAB0MuvWrVNMTIxWrVrV5Lnnn39eGzdu1Jo1a9SzZ89mlz916pRmzpypf/zjH3r11VebDSoXX3yx+vTpo6KiIv361792u9rT6IknnpAkfec732lzzF999ZXsdnub7QB/4YoOAABAJ/LVV1/p+eef13e+8x19//vfb/JYuHChTp48qRdffLHZ5RsaGnTNNdeorKxMGzZsUEpKSrPtIiMjdcstt+jAgQP69a9/3eT5v/3tbyosLFRGRoYuvPBCSdJ//vMfffnll03avvXWW9q7d68mTpzYjsoB73BFBwAAoBN58cUXdfLkSX33u99t9vkLL7xQZ511ltatW+d2F7VGv/zlL/Xiiy9q5syZ+uKLL/TUU0+5Pf8///M/rv+//fbbtWfPHv3ud79TWVmZrr76avXs2VM7duzQU089pREjRugvf/mLq31tba0SExN1zTXXaNSoUTrjjDO0d+9erV27VtHR0VqyZImftgLQNoIOAABAJ7Ju3TpFRES0eKvmsLAwzZgxQ+vWrdPx48ebPF9RUSFJeumll/TSSy81ef70oNOtWzc9++yzeuKJJ/TYY49pyZIl+vrrr3Xuuedq6dKl+uUvf6kzzjjD1T4yMlI33nijXn/9dT333HP6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jh2rVatWebXcgQMHdPToUdcjJibG264BAAAAwCNef3QtMzNTmZmZXncUExOjPn36eL0cAAAAAHirw76jc/7558tut2v06NFatmyZLrroohbb2u122e1213RNTY0kyeFwyOFweNVvY3trmOFxW3+ydmu7X3/37U3N/u5bCk7Np68vGPuamjuub7Md056sr7FWX+sJxHYAACDUBTzoxMfHa82aNZo4caLsdrsee+wxTZs2TW+++abGjx/f7DIFBQXKy8trMr+4uFiRkZE+jSN/orPNNps3b/Zp3a3x9ItWgejbk5oD0Xcwa5aCs6+puWP7lsxzTHuzHW02m+eNT1NfX+/TcgAAdGYBDzrDhg3TsGHDXNNTpkzRRx99pJUrV+rJJ59sdpnc3Fzl5OS4pmtqapSYmKj09HRFRUV51b/D4ZDNZtOS8jDZnZZW2+5bluHVuj0xetlWj9r5s29vavZ331JwapaCu6+puXXBen13hmPak/VZwwzlT3QqLS1N4eHhHq33dI1XxQEA6EqCcnvpSZMmaceOHS0+b7VaZbVam8wPDw/36SQvSXanRfaG1t8U+bruVvtto8+A9u1BzYHoO5g1S8HZ19TcumC9vjvDMe3tdvSlpkC97gAACGVB+cHQiooKxcfHB6NrAAAAAF2A11d0amtrdfDgQdf0oUOHVFFRoX79+mnQoEHKzc3VZ599pieeeEKS9MADDygpKUmjRo3SqVOn9Nhjj+m1115TcXGx/6oAAAAAgNN4HXTKy8t12WWXuaYbv0szb948FRYW6ujRozpy5Ijr+a+//lq//OUv9dlnnykyMlLJycl69dVX3dYBAAAAAP7kddCZNm2aDKPl26EWFha6Td9222267bbbvB4YAAAAAPgqKN/RAQAAAIBAIugAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADTIegAAAAAMB2CDgAAAADT8TrobN++XTNnzlRCQoIs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LBZlZ2dLMu++hrRq1SqdffbZioiI0OTJk/XWW2+12n7Dhg0aPny4IiIiNGbMGG3evNnt+WAeH/6u5YYbbmhyTEyfPj2QJbh4U8v+/ft19dVXu47jBx54oN3r9Cd/19LWuSmQvKnl0Ucf1SWXXKK+ffuqb9++Sk1NbdK+sxwvntTSWY6X559/XhMnTlSfPn10xhln6Pzzz9eTTz7p1sYv+8UwgYyMDGPt2rXGvn37jIqKCuPKK680Bg0aZNTW1rra/PSnPzUSExONkpISo7y83LjwwguNKVOmBHHU7ffiiy8af/vb34x//OMfxoEDB4w77rjDCA8PN/bt22cYhjlrPt1bb71lnH322UZycrKxaNEi13yz1b106VJj1KhRxtGjR12Pf//7367nzVavYRjGF198YQwePNi44YYbjDfffNP45z//aWzdutU4ePCgq83y5cuN6OhoY9OmTcbf//5347vf/a6RlJRkfPXVV0EcefscO3bMbT/bbDZDkvH6668bhmHOfQ3DWL9+vdGjRw/j8ccfN/bv32/cdNNNRp8+fYyqqqpm27/xxhtGt27djHvvvdd47733jDvvvNMIDw839u7d62oTrOMjELXMmzfPmD59utux8cUXXwS0Dl9qeeutt4xbbrnFePrpp424uDhj5cqV7V5nKNfS1rkpULyt5brrrjNWrVpl7Nmzx3j//feNG264wYiOjjY+/fRTV5vOcrx4UktnOV5ef/114/nnnzfee+894+DBg8YDDzxgdOvWzdiyZYurjT/2iymCzrcdO3bMkGRs27bNMAzDOHHihBEeHm5s2LDB1eb99983JBllZWXBGmZA9O3b13jsscdMX/PJkyeNoUOHGjabzZg6daor6Jix7qVLlxpjx45t9jkz1msYhvGrX/3KuPjii1t83ul0GnFxccZ9993nmnfixAnDarUaTz/9dEcMsUMsWrTIOPfccw2n02nafQ3DmDRpkpGdne2abmhoMBISEoyCgoJm2//gBz8wZsyY4TZv8uTJxk9+8hPDMIJ7fPi7FsP45o3brFmzAjLe1nhby+kGDx7cbDhozzrbIxC1tHZuCqT2bsP//Oc/Ru/evY2//OUvhmF0ruPl275di2F0zuOl0bhx44w777zTMAz/7RdTfHTt26qrqyVJ/fr1kyTt3r1bDodDqamprjbDhw/XoEGDVFZWFpQx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K3XZZZepe/fu+utf/6rXX39dd911l/Ly8gJfNACgUyksLNT8+fN19913KykpSQ6HQ5WVlSotLZXNZtOgQYP04osvKjk5OajjPHXqlLp3767u3btLku6//37deuutOnToEJ+IQNAQdID/s3DhQq1atarJlZiWTJ8+XTabTRs3btR3v/tdt+duvfVW3X///Vq+fLl+9atfSZIOHTqksLAwDR482NXOMAylpqbqjTfe0PHjx3XGGWf4ryAAQKfXGHTefvttTZw40e251157Td/5zncUExOj999/Xz179gzSKJsi6CAU8NE1wAPf/o7Orl27tHXrVt1www1NQo4kFRQUaOjQofrd736nr776SpKUlJTkFnKkbz4+l5WVJbvdrn/+858BrQEAYC6XX365lixZosOHD7t9SuGDDz7Q97//ffXr108RERGaOHGiXnzxRbdlGz8S98YbbygnJ0dnnXWWzjjjDH3ve9/Tv//9b7e25eXlysjIUP/+/dWzZ08lJSXpRz/6kVub07+js2zZMt16662Svjn3NX7s7uOPP9bUqVM1duzYZusZNmyYMjIy2rtZABeCDuCDl156SZI0d+7cZp/v3r27rrvuOn355Zd64403Wl1XZWWlJKl///7+HSQAwPR++MMfSpKKi4slSfv379eFF16o999/X7fffrtWrFihM844Q1lZWdq4cWOT5W+++Wb9/e9/19KlS/Wzn/1ML730khYuXOh6/tixY0pPT9fHH3+s22+/XX/84x91/fXXa9euXS2O6aqrrtKcOXMkSStXrtSTTz6pJ598UmeddZZ++MMf6t1339W+ffvclnn77bf1j3/8Q//zP//T7m0CNOoe7AEAndF7770nSS3+q9Tpz73//vtKTU1tts0XX3yhxx57TJdcconi4+P9P1AAgKkNHDhQ0dHR+uijjyRJixYt0qBBg/T222+7vlf685//XBdffLF+9atf6Xvf+57b8meeeaaKi4tlsVgkSU6nU3/4wx9UXV2t6Oho7dy5U19++aWKi4vdPjr3m9/8psUxJScna/z48Xr66aeVlZXl9omI2bNn6+abb9ZTTz2l5cuXu+Y/9dRTOuOMM3TVVVe1e5sAjbiiA/ig8S43vXv3brFN43M1NTXNPu90OnX99dfrxIkT+uMf/+j/QQIAuoRevXrp5MmT+uKLL/Taa6/pBz/4gU6ePKnPP/9cn3/+uY4fP66MjAx9+OGH+uyzz9yW/fGPf+wKOZJ0ySWXqKGhQYcPH5Yk9enTR9I3N9RxOBztHmt0dLRmzZqlp59+2vWd2IaGBj3zzDPKysriu6rwK4IO4IPGENPabT3bCkM333yztmzZoscee6zVK0MAALSmtrZWvXv31sGDB2UYhpYsWaKzzjrL7bF06VJJ33wU7XSDBg1ym+7bt68k6csvv5QkTZ06VVdffbXy8vLUv39/zZo1S2vXrpXdbvd5vHPnztWRI0f0v//7v5KkV199VVVVVa6P4QH+wkfXAB+MGDFCmzZt0rvvvqtLL7202TbvvvuuJGnkyJFNnsvLy9Of/vQnLV++nD/sAACfffrpp6qurtaQIUPkdDolSbfcckuLX+ofMmSI23TjTyB8W+PVFovFoueee067du3SSy+9pK1bt+pHP/qRVqxYoV27dqlXr15ejzkjI0OxsbF66qmndOmll+qpp55SXFxcix/zBnzFFR3AB9/5znckffPbO81paGhQUVGR+vbtq4suusjtuVWrVmnZsmVavHix69bTAAD4ovG33zIyMnTOOedIksLDw5Wamtrso7WPXLfmwgsv1G9/+1uVl5dr3bp12r9/v9avX99i+9M/Dvdt3bp103XXXafnnntOX375pTZt2qQ5c+a0GLoAXxF0AB9MmTJFqampWrt2rV5++eUmz//617/WP/7xD912221uv2vwzDPP6P/9v/+n66+/Xr///e87csgAAJN57bXXlJ+fr6SkJF1//fWKiYnRtGnT9PDDD+vo0aNN2n/7ttGe+PLLL5v8vtz5558vSa1+fK3xuzYnTpxo9vkf/vCH+vLLL/WTn/xEtbW13G0NAcFH1wAfPfHEE7riiis0a9YsXXfddbrkkktkt9v1/PPPq7S0VNdcc43rdwQk6a233tLcuXN15pln6oorrtC6devc1jdlyhTXv8YBAHC6V155RR988IH+85//qKqqSq+99ppsNpsGDx6sF198UREREZK++dTAxRdfrDFjxuimm27SOeeco6qqKpWVlenTTz/V3//+d6/6/ctf/qI//elP+t73vqdzzz1XJ0+e1KOPPqqoqChdeeWVLS43YcIESd/8w9+1116r8PBwzZw50xWAxo0bp9GjR2vDhg0aMWKExo8f7+OWAVpG0AF8FB8fr7feeksrVqzQ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6tatm6qqqtzmV1VVKS4urtllrFarrFar27w+ffq0axxRUVGdage2hlpCE7WEJmr5BldymufLOSouLs6r9lJgzmvBYqZjKpjYjv7BdvSPzrgdPTmvBfxmBD169NCECRNUUlLimud0OlVSUqKUlJRAdw8AQIt8OUelpKS4tZckm83GOQ0AQkyHfHQtJydH8+bN08SJEzVp0iQ98MADqqur0/z58zuiewAAWtTWOWru3LkaMGCACgoKJEmLFi3S1KlTtWLFCs2YMUPr169XeXm5HnnkkWCWAQD4lg4JOtdcc43+/e9/66677lJlZaXOP/98bdmypcmXOQPBarVq6dKlTT4y0BlRS2iiltBELfBUW+eoI0eOKCzsvx+AmDJlioqKinTnnXfqjjvu0NChQ7Vp0yaNHj06WCV0CF6H/sF29A+2o3+YfTtaDO43CgAAAMBkOuQHQwEAAACgIxF0AAAAAJgOQQcAAACA6RB0AAAAAJhOpww6q1at0tlnn62IiAhNnjxZb731VqvtN2zYoOHDhysiIkJjxozR5s2b3Z43DEN33XWX4uPj1bNnT6WmpurDDz8MZAku/q7lhhtukMVicXtMnz49kCW4eFPL/v37dfXVV+vss8+WxWLRAw880O51+pO/a1m2bFmT/TJ8+PAAVvBf3tTy6KOP6pJLLlHfvn3Vt29fpaamNmnfWY4XT2rpLMfL888/r4kTJ6pPnz4644wzdP755+vJJ590axPM/YLOZ/v27Zo5c6YSEhJksVi0adOmNpcpLS3V+PHjZbVaNWTIEBUWFro9H8y/c8Hi7XY8evSorrvuOp133nkKCwvT4sWLm23X1rnebAKxHQsLC5u8HiMiIgJTQIjwdjs+//zzSktL01lnnaWoqCilpKRo69atTdoF672YP3S6oPPMM88oJydHS5cu1TvvvKOxY8cqIyNDx44da7b9zp07NWfOHC1YsEB79uxRVlaWsrKytG/fPlebe++9V3/4wx+0Zs0avfnmmzrjjDOUkZGhU6dOdbpaJGn69Ok6evSo6/H0008HtA5faqmvr9c555yj5cuXt/hr4t6u018CUYskjRo1ym2/7NixI1AluHhbS2lpqebMmaPXX39dZWVlSkxMVHp6uj777DNXm85yvHhSi9Q5jpd+/frp17/+tcrKyvTuu+9q/vz5mj9/vtsJKVj7BZ1TXV2d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",
"text/plain": [
"<Figure size 1000x1000 with 4 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"train.hist(bins=30, figsize=(10, 10))\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Al2O3</th>\n",
" <th>TiO2</th>\n",
" <th>Density</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.06250</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.05979</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.05404</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.05103</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>1.04794</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Al2O3 TiO2 Density\n",
"0 0.0 0.0 1.06250\n",
"1 0.0 0.0 1.05979\n",
"2 0.0 0.0 1.05404\n",
"3 0.0 0.0 1.05103\n",
"4 0.0 0.0 1.04794"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"0 20\n",
"1 25\n",
"2 35\n",
"3 40\n",
"4 45\n",
"Name: T, dtype: int64"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Al2O3</th>\n",
" <th>TiO2</th>\n",
" <th>Density</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0.00</td>\n",
" <td>0.0</td>\n",
" <td>1.05696</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>0.00</td>\n",
" <td>0.0</td>\n",
" <td>1.04158</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>0.05</td>\n",
" <td>0.0</td>\n",
" <td>1.08438</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>0.05</td>\n",
" <td>0.0</td>\n",
" <td>1.08112</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>0.05</td>\n",
" <td>0.0</td>\n",
" <td>1.07781</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Al2O3 TiO2 Density\n",
"0 0.00 0.0 1.05696\n",
"1 0.00 0.0 1.04158\n",
"2 0.05 0.0 1.08438\n",
"3 0.05 0.0 1.08112\n",
"4 0.05 0.0 1.07781"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"0 30\n",
"1 55\n",
"2 25\n",
"3 30\n",
"4 35\n",
"Name: T, dtype: int64"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"y_train = train[\"T\"]\n",
"X_train = train.drop([\"T\"], axis=1)\n",
"\n",
"display(X_train.head())\n",
"display(y_train.head())\n",
"\n",
"y_test = test[\"T\"]\n",
"X_test = test.drop([\"T\"], axis=1)\n",
"\n",
"display(X_test.head())\n",
"display(y_test.head())"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.pipeline import make_pipeline\n",
"from sklearn.preprocessing import PolynomialFeatures\n",
"from sklearn import linear_model, tree, neighbors, ensemble\n",
"\n",
"random_state = 9\n",
"\n",
"models = {\n",
" \"linear\": {\"model\": linear_model.LinearRegression(n_jobs=-1)},\n",
" \"linear_poly\": {\n",
" \"model\": make_pipeline(\n",
" PolynomialFeatures(degree=2),\n",
" linear_model.LinearRegression(fit_intercept=False, n_jobs=-1),\n",
" )\n",
" },\n",
" \"linear_interact\": {\n",
" \"model\": make_pipeline(\n",
" PolynomialFeatures(interaction_only=True),\n",
" linear_model.LinearRegression(fit_intercept=False, n_jobs=-1),\n",
" )\n",
" },\n",
" \"ridge\": {\"model\": linear_model.RidgeCV()},\n",
" \"decision_tree\": {\n",
" \"model\": tree.DecisionTreeRegressor(random_state=random_state, max_depth=6, criterion=\"absolute_error\")\n",
" },\n",
" \"knn\": {\"model\": neighbors.KNeighborsRegressor(n_neighbors=7, n_jobs=-1)},\n",
" \"random_forest\": {\n",
" \"model\": ensemble.RandomForestRegressor(\n",
" max_depth=7, random_state=random_state, n_jobs=-1\n",
" )\n",
" },\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: linear\n",
"Model: linear_poly\n",
"Model: linear_interact\n",
"Model: ridge\n",
"Model: decision_tree\n",
"Model: knn\n",
"Model: random_forest\n"
]
}
],
"source": [
"import math\n",
"from sklearn import metrics\n",
"\n",
"for model_name in models.keys():\n",
" print(f\"Model: {model_name}\")\n",
" fitted_model = models[model_name][\"model\"].fit(\n",
" X_train.values, y_train.values.ravel()\n",
" )\n",
" y_train_pred = fitted_model.predict(X_train.values)\n",
" y_test_pred = fitted_model.predict(X_test.values)\n",
" models[model_name][\"fitted\"] = fitted_model\n",
" models[model_name][\"RMSE_train\"] = math.sqrt(\n",
" metrics.mean_squared_error(y_train, y_train_pred)\n",
" )\n",
" models[model_name][\"RMSE_test\"] = math.sqrt(\n",
" metrics.mean_squared_error(y_test, y_test_pred)\n",
" )\n",
" models[model_name][\"RMAE_test\"] = math.sqrt(\n",
" metrics.mean_absolute_error(y_test, y_test_pred)\n",
" )\n",
" models[model_name][\"R2_test\"] = metrics.r2_score(y_test, y_test_pred)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">\n",
"#T_d72d7_row0_col0, #T_d72d7_row0_col1 {\n",
" background-color: #26818e;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row0_col2, #T_d72d7_row6_col3 {\n",
" background-color: #4e02a2;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row0_col3, #T_d72d7_row6_col2 {\n",
" background-color: #da5a6a;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row1_col0 {\n",
" background-color: #20928c;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row1_col1 {\n",
" background-color: #1f968b;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row1_col2 {\n",
" background-color: #8a09a5;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row1_col3 {\n",
" background-color: #d5536f;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row2_col0, #T_d72d7_row3_col0 {\n",
" background-color: #20938c;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row2_col1 {\n",
" background-color: #1f9a8a;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row2_col2 {\n",
" background-color: #8e0ca4;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row2_col3 {\n",
" background-color: #d35171;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row3_col1 {\n",
" background-color: #2cb17e;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row3_col2 {\n",
" background-color: #b02991;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row3_col3 {\n",
" background-color: #c23c81;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row4_col0 {\n",
" background-color: #1e9c89;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row4_col1 {\n",
" background-color: #31b57b;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row4_col2 {\n",
" background-color: #b7318a;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row4_col3 {\n",
" background-color: #be3885;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row5_col0 {\n",
" background-color: #7ad151;\n",
" color: #000000;\n",
"}\n",
"#T_d72d7_row5_col1 {\n",
" background-color: #a2da37;\n",
" color: #000000;\n",
"}\n",
"#T_d72d7_row5_col2 {\n",
" background-color: #d6556d;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row5_col3 {\n",
" background-color: #5601a4;\n",
" color: #f1f1f1;\n",
"}\n",
"#T_d72d7_row6_col0, #T_d72d7_row6_col1 {\n",
" background-color: #a8db34;\n",
" color: #000000;\n",
"}\n",
"</style>\n",
"<table id=\"T_d72d7\">\n",
" <thead>\n",
" <tr>\n",
" <th class=\"blank level0\" >&nbsp;</th>\n",
" <th id=\"T_d72d7_level0_col0\" class=\"col_heading level0 col0\" >RMSE_train</th>\n",
" <th id=\"T_d72d7_level0_col1\" class=\"col_heading level0 col1\" >RMSE_test</th>\n",
" <th id=\"T_d72d7_level0_col2\" class=\"col_heading level0 col2\" >RMAE_test</th>\n",
" <th id=\"T_d72d7_level0_col3\" class=\"col_heading level0 col3\" >R2_test</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th id=\"T_d72d7_level0_row0\" class=\"row_heading level0 row0\" >linear_poly</th>\n",
" <td id=\"T_d72d7_row0_col0\" class=\"data row0 col0\" >0.550244</td>\n",
" <td id=\"T_d72d7_row0_col1\" class=\"data row0 col1\" >0.450880</td>\n",
" <td id=\"T_d72d7_row0_col2\" class=\"data row0 col2\" >0.626648</td>\n",
" <td id=\"T_d72d7_row0_col3\" class=\"data row0 col3\" >0.999047</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_d72d7_level0_row1\" class=\"row_heading level0 row1\" >linear_interact</th>\n",
" <td id=\"T_d72d7_row1_col0\" class=\"data row1 col0\" >3.113410</td>\n",
" <td id=\"T_d72d7_row1_col1\" class=\"data row1 col1\" >3.297794</td>\n",
" <td id=\"T_d72d7_row1_col2\" class=\"data row1 col2\" >1.648764</td>\n",
" <td id=\"T_d72d7_row1_col3\" class=\"data row1 col3\" >0.949019</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_d72d7_level0_row2\" class=\"row_heading level0 row2\" >linear</th>\n",
" <td id=\"T_d72d7_row2_col0\" class=\"data row2 col0\" >3.235507</td>\n",
" <td id=\"T_d72d7_row2_col1\" class=\"data row2 col1\" >3.849716</td>\n",
" <td id=\"T_d72d7_row2_col2\" class=\"data row2 col2\" >1.711791</td>\n",
" <td id=\"T_d72d7_row2_col3\" class=\"data row2 col3\" >0.930526</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_d72d7_level0_row3\" class=\"row_heading level0 row3\" >decision_tree</th>\n",
" <td id=\"T_d72d7_row3_col0\" class=\"data row3 col0\" >3.244428</td>\n",
" <td id=\"T_d72d7_row3_col1\" class=\"data row3 col1\" >6.886688</td>\n",
" <td id=\"T_d72d7_row3_col2\" class=\"data row3 col2\" >2.394847</td>\n",
" <td id=\"T_d72d7_row3_col3\" class=\"data row3 col3\" >0.777676</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_d72d7_level0_row4\" class=\"row_heading level0 row4\" >random_forest</th>\n",
" <td id=\"T_d72d7_row4_col0\" class=\"data row4 col0\" >4.499320</td>\n",
" <td id=\"T_d72d7_row4_col1\" class=\"data row4 col1\" >7.382496</td>\n",
" <td id=\"T_d72d7_row4_col2\" class=\"data row4 col2\" >2.568683</td>\n",
" <td id=\"T_d72d7_row4_col3\" class=\"data row4 col3\" >0.744512</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_d72d7_level0_row5\" class=\"row_heading level0 row5\" >knn</th>\n",
" <td id=\"T_d72d7_row5_col0\" class=\"data row5 col0\" >13.194712</td>\n",
" <td id=\"T_d72d7_row5_col1\" class=\"data row5 col1\" >13.826658</td>\n",
" <td id=\"T_d72d7_row5_col2\" class=\"data row5 col2\" >3.417700</td>\n",
" <td id=\"T_d72d7_row5_col3\" class=\"data row5 col3\" >0.103812</td>\n",
" </tr>\n",
" <tr>\n",
" <th id=\"T_d72d7_level0_row6\" class=\"row_heading level0 row6\" >ridge</th>\n",
" <td id=\"T_d72d7_row6_col0\" class=\"data row6 col0\" >15.600149</td>\n",
" <td id=\"T_d72d7_row6_col1\" class=\"data row6 col1\" >14.128039</td>\n",
" <td id=\"T_d72d7_row6_col2\" class=\"data row6 col2\" >3.520909</td>\n",
" <td id=\"T_d72d7_row6_col3\" class=\"data row6 col3\" >0.064317</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n"
],
"text/plain": [
"<pandas.io.formats.style.Styler at 0x16a2ae420>"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"reg_metrics = pd.DataFrame.from_dict(models, \"index\")[\n",
" [\"RMSE_train\", \"RMSE_test\", \"RMAE_test\", \"R2_test\"]\n",
"]\n",
"reg_metrics.sort_values(by=\"RMSE_test\").style.background_gradient(\n",
" cmap=\"viridis\", low=1, high=0.3, subset=[\"RMSE_train\", \"RMSE_test\"]\n",
").background_gradient(cmap=\"plasma\", low=0.3, high=1, subset=[\"RMAE_test\", \"R2_test\"])"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/user/Projects/python/fuzzy-rules-generator/.venv/lib/python3.12/site-packages/numpy/ma/core.py:2881: RuntimeWarning: invalid value encountered in cast\n",
" _data = np.array(data, dtype=dtype, copy=copy,\n"
]
},
{
"data": {
"text/plain": [
"{'criterion': 'poisson', 'max_depth': 5, 'min_samples_split': 4}"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"from sklearn import model_selection\n",
"\n",
"parameters = {\n",
" \"criterion\": [\"squared_error\", \"absolute_error\", \"friedman_mse\", \"poisson\"],\n",
" \"max_depth\": np.arange(1, 21).tolist()[0::2],\n",
" \"min_samples_split\": np.arange(2, 11).tolist()[0::2],\n",
"}\n",
"\n",
"grid = model_selection.GridSearchCV(\n",
" tree.DecisionTreeRegressor(random_state=random_state),\n",
" parameters,\n",
" cv=4,\n",
" n_jobs=-1,\n",
" scoring=\"r2\",\n",
")\n",
"\n",
"grid.fit(X_test, y_test)\n",
"grid.best_params_"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'RMSE_test': 6.886687925863586,\n",
" 'RMAE_test': 2.394847410096739,\n",
" 'R2_test': 0.777676399026764}"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"{'RMSE_test': 8.194929087252557,\n",
" 'RMAE_test': 2.5048971643405977,\n",
" 'MAE_test': 6.274509803921568,\n",
" 'R2_test': 0.6851851851851851}"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"model = grid.best_estimator_\n",
"y_pred = model.predict(X_test)\n",
"old_metrics = {\n",
" \"RMSE_test\": models[\"decision_tree\"][\"RMSE_test\"],\n",
" \"RMAE_test\": models[\"decision_tree\"][\"RMAE_test\"],\n",
" \"R2_test\": models[\"decision_tree\"][\"R2_test\"],\n",
"}\n",
"new_metrics = {}\n",
"new_metrics[\"RMSE_test\"] = math.sqrt(metrics.mean_squared_error(y_test, y_pred))\n",
"new_metrics[\"RMAE_test\"] = math.sqrt(metrics.mean_absolute_error(y_test, y_pred))\n",
"new_metrics[\"MAE_test\"] = float(metrics.mean_absolute_error(y_test, y_pred))\n",
"new_metrics[\"R2_test\"] = metrics.r2_score(y_test, y_pred)\n",
"\n",
"display(old_metrics)\n",
"display(new_metrics)"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"|--- Density <= 1.04\n",
"| |--- Density <= 1.03\n",
"| | |--- value: [70.00]\n",
"| |--- Density > 1.03\n",
"| | |--- Density <= 1.04\n",
"| | | |--- value: [65.00]\n",
"| | |--- Density > 1.04\n",
"| | | |--- value: [60.00]\n",
"|--- Density > 1.04\n",
"| |--- Density <= 1.07\n",
"| | |--- TiO2 <= 0.03\n",
"| | | |--- Al2O3 <= 0.03\n",
"| | | | |--- Density <= 1.05\n",
"| | | | | |--- Density <= 1.05\n",
"| | | | | | |--- value: [50.00]\n",
"| | | | | |--- Density > 1.05\n",
"| | | | | | |--- value: [42.50]\n",
"| | | | |--- Density > 1.05\n",
"| | | | | |--- Density <= 1.06\n",
"| | | | | | |--- value: [35.00]\n",
"| | | | | |--- Density > 1.06\n",
"| | | | | | |--- value: [22.50]\n",
"| | | |--- Al2O3 > 0.03\n",
"| | | | |--- Density <= 1.06\n",
"| | | | | |--- Density <= 1.05\n",
"| | | | | | |--- value: [70.00]\n",
"| | | | | |--- Density > 1.05\n",
"| | | | | | |--- value: [65.00]\n",
"| | | | |--- Density > 1.06\n",
"| | | | | |--- Density <= 1.07\n",
"| | | | | | |--- value: [55.00]\n",
"| | | | | |--- Density > 1.07\n",
"| | | | | | |--- value: [50.00]\n",
"| | |--- TiO2 > 0.03\n",
"| | | |--- Density <= 1.06\n",
"| | | | |--- value: [70.00]\n",
"| | | |--- Density > 1.06\n",
"| | | | |--- Density <= 1.06\n",
"| | | | | |--- value: [65.00]\n",
"| | | | |--- Density > 1.06\n",
"| | | | | |--- value: [60.00]\n",
"| |--- Density > 1.07\n",
"| | |--- Density <= 1.12\n",
"| | | |--- Density <= 1.08\n",
"| | | | |--- Density <= 1.07\n",
"| | | | | |--- value: [45.00]\n",
"| | | | |--- Density > 1.07\n",
"| | | | | |--- Density <= 1.08\n",
"| | | | | | |--- value: [40.00]\n",
"| | | | | |--- Density > 1.08\n",
"| | | | | | |--- value: [35.00]\n",
"| | | |--- Density > 1.08\n",
"| | | | |--- Density <= 1.09\n",
"| | | | | |--- value: [30.00]\n",
"| | | | |--- Density > 1.09\n",
"| | | | | |--- Al2O3 <= 0.03\n",
"| | | | | | |--- value: [22.50]\n",
"| | | | | |--- Al2O3 > 0.03\n",
"| | | | | | |--- value: [20.00]\n",
"| | |--- Density > 1.12\n",
"| | | |--- Density <= 1.18\n",
"| | | | |--- Density <= 1.15\n",
"| | | | | |--- value: [70.00]\n",
"| | | | |--- Density > 1.15\n",
"| | | | | |--- Al2O3 <= 0.15\n",
"| | | | | | |--- value: [65.00]\n",
"| | | | | |--- Al2O3 > 0.15\n",
"| | | | | | |--- value: [50.00]\n",
"| | | |--- Density > 1.18\n",
"| | | | |--- Al2O3 <= 0.15\n",
"| | | | | |--- Density <= 1.20\n",
"| | | | | | |--- value: [50.00]\n",
"| | | | | |--- Density > 1.20\n",
"| | | | | | |--- value: [30.00]\n",
"| | | | |--- Al2O3 > 0.15\n",
"| | | | | |--- Density <= 1.18\n",
"| | | | | | |--- value: [30.00]\n",
"| | | | | |--- Density > 1.18\n",
"| | | | | | |--- value: [22.50]\n",
"\n"
]
}
],
"source": [
"rules = tree.export_text(\n",
" models[\"decision_tree\"][\"fitted\"], feature_names=X_train.columns.values.tolist()\n",
")\n",
"print(rules)"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [],
"source": [
"import pickle\n",
"\n",
"pickle.dump(\n",
" models[\"decision_tree\"][\"fitted\"], open(\"data/temp_density_tree.model.sav\", \"wb\")\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"|--- Density <= 1.21\n",
"| |--- TiO2 <= 0.03\n",
"| | |--- Density <= 1.07\n",
"| | | |--- value: [48.33]\n",
"| | |--- Density > 1.07\n",
"| | | |--- Al2O3 <= 0.18\n",
"| | | | |--- Density <= 1.08\n",
"| | | | | |--- value: [37.50]\n",
"| | | | |--- Density > 1.08\n",
"| | | | | |--- value: [27.50]\n",
"| | | |--- Al2O3 > 0.18\n",
"| | | | |--- value: [50.00]\n",
"| |--- TiO2 > 0.03\n",
"| | |--- Density <= 1.19\n",
"| | | |--- TiO2 <= 0.18\n",
"| | | | |--- value: [50.00]\n",
"| | | |--- TiO2 > 0.18\n",
"| | | | |--- value: [65.00]\n",
"| | |--- Density > 1.19\n",
"| | | |--- value: [40.00]\n",
"|--- Density > 1.21\n",
"| |--- value: [25.00]\n",
"\n"
]
}
],
"source": [
"rules2 = tree.export_text(model, feature_names=X_train.columns.values.tolist())\n",
"print(rules2)"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [],
"source": [
"import pickle\n",
"\n",
"pickle.dump(model, open(\"data/temp_density_tree-gs.model.sav\", \"wb\"))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.9"
}
},
"nbformat": 4,
"nbformat_minor": 2
}