{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Generating rules with RuleKit\n", "\n", "Currently decision-rules does not generate rules. You can, however, generate rules using RuleKit and convert the model into decision-rules rule set.\n", "\n", "We will start by importing the RuleKit package." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "from rulekit import RuleKit\n", "from rulekit.classification import RuleClassifier\n", "from rulekit.params import Measures\n", "\n", "RuleKit.init()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will use the following zoo dataset:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
hairfeatherseggsmilkairborneaquaticpredatortoothedbackbonebreathesvenomousfinslegstaildomesticcatsizeclass
0TrueFalseFalseTrueFalseFalseTrueTrueTrueTrueFalseFalse4.0FalseFalseTruemammal
1TrueFalseFalseTrueFalseFalseFalseTrueTrueTrueFalseFalse4.0TrueFalseTruemammal
2FalseFalseTrueFalseFalseTrueTrueTrueTrueFalseFalseTrue0.0TrueFalseFalsefish
3TrueFalseFalseTrueFalseFalseTrueTrueTrueTrueFalseFalse4.0FalseFalseTruemammal
4TrueFalseFalseTrueFalseFalseTrueTrueTrueTrueFalseFalse4.0TrueFalseTruemammal
......................................................
96TrueFalseFalseTrueFalseFalseFalseTrueTrueTrueFalseFalse2.0TrueFalseTruemammal
97TrueFalseTrueFalseTrueFalseFalseFalseFalseTrueTrueFalse6.0FalseFalseFalseinsect
98TrueFalseFalseTrueFalseFalseTrueTrueTrueTrueFalseFalse4.0TrueFalseTruemammal
99FalseFalseTrueFalseFalseFalseFalseFalseFalseTrueFalseFalse0.0FalseFalseFalseinvertebrate
100FalseTrueTrueFalseTrueFalseFalseFalseTrueTrueFalseFalse2.0TrueFalseFalsebird
\n", "

101 rows × 17 columns

\n", "
" ], "text/plain": [ " hair feathers eggs milk airborne aquatic predator toothed \\\n", "0 True False False True False False True True \n", "1 True False False True False False False True \n", "2 False False True False False True True True \n", "3 True False False True False False True True \n", "4 True False False True False False True True \n", ".. ... ... ... ... ... ... ... ... \n", "96 True False False True False False False True \n", "97 True False True False True False False False \n", "98 True False False True False False True True \n", "99 False False True False False False False False \n", "100 False True True False True False False False \n", "\n", " backbone breathes venomous fins legs tail domestic catsize \\\n", "0 True True False False 4.0 False False True \n", "1 True True False False 4.0 True False True \n", "2 True False False True 0.0 True False False \n", "3 True True False False 4.0 False False True \n", "4 True True False False 4.0 True False True \n", ".. ... ... ... ... ... ... ... ... \n", "96 True True False False 2.0 True False True \n", "97 False True True False 6.0 False False False \n", "98 True True False False 4.0 True False True \n", "99 False True False False 0.0 False False False \n", "100 True True False False 2.0 True False False \n", "\n", " class \n", "0 mammal \n", "1 mammal \n", "2 fish \n", "3 mammal \n", "4 mammal \n", ".. ... \n", "96 mammal \n", "97 insect \n", "98 mammal \n", "99 invertebrate \n", "100 bird \n", "\n", "[101 rows x 17 columns]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df = pd.read_csv(\"resources/zoo.csv\")\n", "display(df)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `class` column will be our target `y` and the other columns will be predictors `X`." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "X = df.drop(\"class\", axis=1)\n", "y = df[\"class\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we will generate the rules using RuleKit. We just need to create a `RuleClassifier` object and train it using the `fit` function." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rulekit_model = RuleClassifier()\n", "rulekit_model.fit(X, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's see the generated rules." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "IF aquatic = <0.50, inf) AND legs = <3, inf) AND toothed = <0.50, inf) AND hair = (-inf, 0.50) THEN class = {amphibian}\n", "IF feathers = <0.50, inf) THEN class = {bird}\n", "IF fins = <0.50, inf) AND eggs = <0.50, inf) THEN class = {fish}\n", "IF legs = <5.50, inf) AND aquatic = (-inf, 0.50) AND eggs = <0.50, inf) THEN class = {insect}\n", "IF backbone = (-inf, 0.50) AND airborne = (-inf, 0.50) THEN class = {invertebrate}\n", "IF milk = <0.50, inf) THEN class = {mammal}\n", "IF toothed = <0.50, inf) AND fins = (-inf, 0.50) AND legs = (-inf, 2) THEN class = {reptile}\n", "IF hair = (-inf, 0.50) AND toothed = <0.50, inf) AND aquatic = (-inf, 0.50) THEN class = {reptile}\n", "IF hair = (-inf, 0.50) AND feathers = (-inf, 0.50) AND aquatic = (-inf, 0.50) AND backbone = <0.50, inf) THEN class = {reptile}\n" ] } ], "source": [ "\n", "for rule in rulekit_model.model.rules:\n", " print(rule)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `RuleKitRuleSetFactory` from `ruleset_factories` converts the RuleKit model to decision-rules rule set." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from ruleset_factories._factories.classification import RuleKitRuleSetFactory\n", "factory = RuleKitRuleSetFactory()\n", "decision_rules_ruleset = factory.make(rulekit_model, X, y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's check if the rules in `decision_rules_ruleset` are the same as in `rulekit_model`." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "IF aquatic >= 0.50 AND legs >= 3.00 AND toothed >= 0.50 AND hair < 0.50 THEN class = amphibian (p=4, n=0, P=4, N=97)\n", "IF feathers >= 0.50 THEN class = bird (p=20, n=0, P=20, N=81)\n", "IF fins >= 0.50 AND eggs >= 0.50 THEN class = fish (p=13, n=0, P=13, N=88)\n", "IF legs >= 5.50 AND aquatic < 0.50 AND eggs >= 0.50 THEN class = insect (p=8, n=0, P=8, N=93)\n", "IF backbone < 0.50 AND airborne < 0.50 THEN class = invertebrate (p=10, n=2, P=10, N=91)\n", "IF milk >= 0.50 THEN class = mammal (p=41, n=0, P=41, N=60)\n", "IF toothed >= 0.50 AND fins < 0.50 AND legs < 2.00 THEN class = reptile (p=3, n=0, P=5, N=96)\n", "IF hair < 0.50 AND toothed >= 0.50 AND aquatic < 0.50 THEN class = reptile (p=3, n=0, P=5, N=96)\n", "IF hair < 0.50 AND feathers < 0.50 AND aquatic < 0.50 AND backbone >= 0.50 THEN class = reptile (p=4, n=0, P=5, N=96)\n" ] } ], "source": [ "for rule in decision_rules_ruleset.rules:\n", " print(rule)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now predict values using `decision_rules_ruleset` and calculate various statistics describing the rules." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['mammal', 'mammal', 'fish', 'mammal', 'mammal', 'mammal', 'mammal',\n", " 'fish', 'fish', 'mammal', 'mammal', 'bird', 'fish', 'invertebrate',\n", " 'invertebrate', 'invertebrate', 'bird', 'mammal', 'fish', 'mammal',\n", " 'bird', 'bird', 'mammal', 'bird', 'insect', 'amphibian',\n", " 'amphibian', 'mammal', 'mammal', 'mammal', 'insect', 'mammal',\n", " 'mammal', 'bird', 'fish', 'mammal', 'mammal', 'bird', 'fish',\n", " 'insect', 'insect', 'bird', 'insect', 'bird', 'mammal', 'mammal',\n", " 'invertebrate', 'mammal', 'mammal', 'mammal', 'mammal', 'insect',\n", " 'amphibian', 'invertebrate', 'mammal', 'mammal', 'bird', 'bird',\n", " 'bird', 'bird', 'fish', 'fish', 'reptile', 'mammal', 'mammal',\n", " 'mammal', 'mammal', 'mammal', 'mammal', 'mammal', 'mammal', 'bird',\n", " 'invertebrate', 'fish', 'mammal', 'mammal', 'reptile',\n", " 'invertebrate', 'bird', 'bird', 'reptile', 'invertebrate', 'fish',\n", " 'bird', 'mammal', 'invertebrate', 'fish', 'bird', 'insect',\n", " 'amphibian', 'reptile', 'reptile', 'fish', 'mammal', 'mammal',\n", " 'bird', 'mammal', 'insect', 'mammal', 'invertebrate', 'bird'],\n", " dtype='= 3.00',\n", " 'attributes': ['legs'],\n", " 'importance': 0.21835455831817263},\n", " {'condition': 'toothed >= 0.50',\n", " 'attributes': ['toothed'],\n", " 'importance': 0.15137644827521457},\n", " {'condition': 'aquatic >= 0.50',\n", " 'attributes': ['aquatic'],\n", " 'importance': 0.0706758304696449},\n", " {'condition': 'hair < 0.50',\n", " 'attributes': ['hair'],\n", " 'importance': 0.05970494134376112}],\n", " 'bird': [{'condition': 'feathers >= 0.50',\n", " 'attributes': ['feathers'],\n", " 'importance': 1.0}],\n", " 'fish': [{'condition': 'fins >= 0.50',\n", " 'attributes': ['fins'],\n", " 'importance': 0.812392368349497},\n", " {'condition': 'eggs >= 0.50',\n", " 'attributes': ['eggs'],\n", " 'importance': 0.187607631650503}],\n", " 'insect': [{'condition': 'legs >= 5.50',\n", " 'attributes': ['legs'],\n", " 'importance': 0.47480739916779957},\n", " {'condition': 'aquatic < 0.50',\n", " 'attributes': ['aquatic'],\n", " 'importance': 0.11461012106173396},\n", " {'condition': 'eggs >= 0.50',\n", " 'attributes': ['eggs'],\n", " 'importance': 0.060634901349317274}],\n", " 'invertebrate': [{'condition': 'backbone < 0.50',\n", " 'attributes': ['backbone'],\n", " 'importance': 0.6437411794554653},\n", " {'condition': 'airborne < 0.50',\n", " 'attributes': ['airborne'],\n", " 'importance': 0.17127713556284985}],\n", " 'mammal': [{'condition': 'milk >= 0.50',\n", " 'attributes': ['milk'],\n", " 'importance': 1.0}],\n", " 'reptile': [{'condition': 'hair < 0.50',\n", " 'attributes': ['hair'],\n", " 'importance': 0.49337088161384896},\n", " {'condition': 'aquatic < 0.50',\n", " 'attributes': ['aquatic'],\n", " 'importance': 0.4172718233231141},\n", " {'condition': 'toothed >= 0.50',\n", " 'attributes': ['toothed'],\n", " 'importance': 0.4041948772993855},\n", " {'condition': 'legs < 2.00',\n", " 'attributes': ['legs'],\n", " 'importance': 0.2763037988581467},\n", " {'condition': 'fins < 0.50',\n", " 'attributes': ['fins'],\n", " 'importance': 0.23977086814257867},\n", " {'condition': 'feathers < 0.50',\n", " 'attributes': ['feathers'],\n", " 'importance': 0.18732960390946504},\n", " {'condition': 'backbone >= 0.50',\n", " 'attributes': ['backbone'],\n", " 'importance': 0.16063629518072292}]}" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Attribute importances:\n" ] }, { "data": { "text/plain": [ "{'amphibian': {'legs': 0.21835455831817263,\n", " 'toothed': 0.15137644827521457,\n", " 'aquatic': 0.0706758304696449,\n", " 'hair': 0.05970494134376112},\n", " 'bird': {'feathers': 1.0},\n", " 'fish': {'fins': 0.812392368349497, 'eggs': 0.187607631650503},\n", " 'insect': {'legs': 0.47480739916779957,\n", " 'aquatic': 0.11461012106173396,\n", " 'eggs': 0.060634901349317274},\n", " 'invertebrate': {'backbone': 0.6437411794554653,\n", " 'airborne': 0.17127713556284985},\n", " 'mammal': {'milk': 1.0},\n", " 'reptile': {'hair': 0.49337088161384896,\n", " 'aquatic': 0.4172718233231141,\n", " 'toothed': 0.4041948772993855,\n", " 'legs': 0.2763037988581467,\n", " 'fins': 0.23977086814257867,\n", " 'feathers': 0.18732960390946504,\n", " 'backbone': 0.16063629518072292}}" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from decision_rules.measures import c2\n", "condition_importances = decision_rules_ruleset.calculate_condition_importances(X, y, measure=c2)\n", "print('Condition importances:')\n", "display(condition_importances)\n", "attribute_importances = decision_rules_ruleset.calculate_attribute_importances(condition_importances)\n", "print('Attribute importances:')\n", "display(attribute_importances)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can serialize the decision-rules rule set to Python dict which can be later stored in JSON format. We do it using `JSONSerializer.serialize`." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "from decision_rules.serialization.utils import JSONSerializer\n", "from decision_rules.classification.ruleset import ClassificationRuleSet" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'meta': {'attributes': ['hair', 'feathers', 'eggs', 'milk', 'airborne', 'aquatic', 'predator', 'toothed', 'backbone', 'breathes', 'venomous', 'fins', 'legs', 'tail', 'domestic', 'catsize'], 'decision_attribute': 'class', 'decision_attribute_distribution': {'amphibian': 4, 'bird': 20, 'fish': 13, 'insect': 8, 'invertebrate': 10, 'mammal': 41, 'reptile': 5}}, 'rules': [{'uuid': '3357850a-4701-41ee-92f5-17d524564033', 'string': 'IF aquatic >= 0.50 AND legs >= 3.00 AND toothed >= 0.50 AND hair < 0.50 THEN class = amphibian', 'premise': {'type': 'compound', 'operator': 'CONJUNCTION', 'subconditions': [{'type': 'elementary_numerical', 'attributes': [5], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [12], 'negated': False, 'left': 3.0, 'right': None, 'left_closed': True, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [7], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [0], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}]}, 'conclusion': {'value': 'amphibian'}, 'coverage': {'p': 4, 'n': 0, 'P': 4, 'N': 97}}, {'uuid': '0d28724c-56c4-47bb-847e-96fc60e191d9', 'string': 'IF feathers >= 0.50 THEN class = bird', 'premise': {'type': 'compound', 'operator': 'CONJUNCTION', 'subconditions': [{'type': 'elementary_numerical', 'attributes': [1], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}]}, 'conclusion': {'value': 'bird'}, 'coverage': {'p': 20, 'n': 0, 'P': 20, 'N': 81}}, {'uuid': '9804e9ab-07d5-4954-8a32-22cb0033196a', 'string': 'IF fins >= 0.50 AND eggs >= 0.50 THEN class = fish', 'premise': {'type': 'compound', 'operator': 'CONJUNCTION', 'subconditions': [{'type': 'elementary_numerical', 'attributes': [11], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [2], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}]}, 'conclusion': {'value': 'fish'}, 'coverage': {'p': 13, 'n': 0, 'P': 13, 'N': 88}}, {'uuid': 'd7aa0f70-1492-4114-99f7-2a26a000c366', 'string': 'IF legs >= 5.50 AND aquatic < 0.50 AND eggs >= 0.50 THEN class = insect', 'premise': {'type': 'compound', 'operator': 'CONJUNCTION', 'subconditions': [{'type': 'elementary_numerical', 'attributes': [12], 'negated': False, 'left': 5.5, 'right': None, 'left_closed': True, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [5], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [2], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}]}, 'conclusion': {'value': 'insect'}, 'coverage': {'p': 8, 'n': 0, 'P': 8, 'N': 93}}, {'uuid': '787b7170-b084-4830-a995-dd39cfe2ca15', 'string': 'IF backbone < 0.50 AND airborne < 0.50 THEN class = invertebrate', 'premise': {'type': 'compound', 'operator': 'CONJUNCTION', 'subconditions': [{'type': 'elementary_numerical', 'attributes': [8], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [4], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}]}, 'conclusion': {'value': 'invertebrate'}, 'coverage': {'p': 10, 'n': 2, 'P': 10, 'N': 91}}, {'uuid': '67f18dcb-1a70-43ad-9e16-713daedc5eca', 'string': 'IF milk >= 0.50 THEN class = mammal', 'premise': {'type': 'compound', 'operator': 'CONJUNCTION', 'subconditions': [{'type': 'elementary_numerical', 'attributes': [3], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}]}, 'conclusion': {'value': 'mammal'}, 'coverage': {'p': 41, 'n': 0, 'P': 41, 'N': 60}}, {'uuid': 'd122f503-9a1c-40b4-a879-a8452235ef9f', 'string': 'IF toothed >= 0.50 AND fins < 0.50 AND legs < 2.00 THEN class = reptile', 'premise': {'type': 'compound', 'operator': 'CONJUNCTION', 'subconditions': [{'type': 'elementary_numerical', 'attributes': [7], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [11], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [12], 'negated': False, 'left': None, 'right': 2.0, 'left_closed': False, 'right_closed': False}]}, 'conclusion': {'value': 'reptile'}, 'coverage': {'p': 3, 'n': 0, 'P': 5, 'N': 96}}, {'uuid': 'cce9a48a-ffd9-4636-9330-c9c991d0a15d', 'string': 'IF hair < 0.50 AND toothed >= 0.50 AND aquatic < 0.50 THEN class = reptile', 'premise': {'type': 'compound', 'operator': 'CONJUNCTION', 'subconditions': [{'type': 'elementary_numerical', 'attributes': [0], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [7], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [5], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}]}, 'conclusion': {'value': 'reptile'}, 'coverage': {'p': 3, 'n': 0, 'P': 5, 'N': 96}}, {'uuid': '0485665e-f92e-42f5-86e5-d05625076cd8', 'string': 'IF hair < 0.50 AND feathers < 0.50 AND aquatic < 0.50 AND backbone >= 0.50 THEN class = reptile', 'premise': {'type': 'compound', 'operator': 'CONJUNCTION', 'subconditions': [{'type': 'elementary_numerical', 'attributes': [0], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [1], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [5], 'negated': False, 'left': None, 'right': 0.5, 'left_closed': False, 'right_closed': False}, {'type': 'elementary_numerical', 'attributes': [8], 'negated': False, 'left': 0.5, 'right': None, 'left_closed': True, 'right_closed': False}]}, 'conclusion': {'value': 'reptile'}, 'coverage': {'p': 4, 'n': 0, 'P': 5, 'N': 96}}]}\n" ] } ], "source": [ "ruleset_json = JSONSerializer.serialize(decision_rules_ruleset)\n", "print(ruleset_json)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "import json \n", "with open('output/zoo.json', 'w') as f:\n", " json.dump(ruleset_json, f)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The serialized ruleset can be reloaded using `JSONSerializer.deserialize`." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "with open('output/zoo.json') as f:\n", " deserialized_ruleset_json = json.load(f)\n", "deserialized_ruleset = JSONSerializer.deserialize(deserialized_ruleset_json, target_class=ClassificationRuleSet)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's check if the rules are the same." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "IF aquatic >= 0.50 AND legs >= 3.00 AND toothed >= 0.50 AND hair < 0.50 THEN class = amphibian (p=4, n=0, P=4, N=97)\n", "IF feathers >= 0.50 THEN class = bird (p=20, n=0, P=20, N=81)\n", "IF fins >= 0.50 AND eggs >= 0.50 THEN class = fish (p=13, n=0, P=13, N=88)\n", "IF legs >= 5.50 AND aquatic < 0.50 AND eggs >= 0.50 THEN class = insect (p=8, n=0, P=8, N=93)\n", "IF backbone < 0.50 AND airborne < 0.50 THEN class = invertebrate (p=10, n=2, P=10, N=91)\n", "IF milk >= 0.50 THEN class = mammal (p=41, n=0, P=41, N=60)\n", "IF toothed >= 0.50 AND fins < 0.50 AND legs < 2.00 THEN class = reptile (p=3, n=0, P=5, N=96)\n", "IF hair < 0.50 AND toothed >= 0.50 AND aquatic < 0.50 THEN class = reptile (p=3, n=0, P=5, N=96)\n", "IF hair < 0.50 AND feathers < 0.50 AND aquatic < 0.50 AND backbone >= 0.50 THEN class = reptile (p=4, n=0, P=5, N=96)\n" ] } ], "source": [ "for rule in deserialized_ruleset.rules:\n", " print(rule)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before using some of the functions of the deserialized ruleset, it may be necessary to call the `update` function. After that the object will be ready for prediction." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['mammal', 'mammal', 'fish', 'mammal', 'mammal', 'mammal', 'mammal',\n", " 'fish', 'fish', 'mammal', 'mammal', 'bird', 'fish', 'invertebrate',\n", " 'invertebrate', 'invertebrate', 'bird', 'mammal', 'fish', 'mammal',\n", " 'bird', 'bird', 'mammal', 'bird', 'insect', 'amphibian',\n", " 'amphibian', 'mammal', 'mammal', 'mammal', 'insect', 'mammal',\n", " 'mammal', 'bird', 'fish', 'mammal', 'mammal', 'bird', 'fish',\n", " 'insect', 'insect', 'bird', 'insect', 'bird', 'mammal', 'mammal',\n", " 'invertebrate', 'mammal', 'mammal', 'mammal', 'mammal', 'insect',\n", " 'amphibian', 'invertebrate', 'mammal', 'mammal', 'bird', 'bird',\n", " 'bird', 'bird', 'fish', 'fish', 'reptile', 'mammal', 'mammal',\n", " 'mammal', 'mammal', 'mammal', 'mammal', 'mammal', 'mammal', 'bird',\n", " 'invertebrate', 'fish', 'mammal', 'mammal', 'reptile',\n", " 'invertebrate', 'bird', 'bird', 'reptile', 'invertebrate', 'fish',\n", " 'bird', 'mammal', 'invertebrate', 'fish', 'bird', 'insect',\n", " 'amphibian', 'reptile', 'reptile', 'fish', 'mammal', 'mammal',\n", " 'bird', 'mammal', 'insect', 'mammal', 'invertebrate', 'bird'],\n", " dtype='