Evan Gertis
Evan Gertis

Reputation: 2052

Recursively Incrementing Over Nested Dictionary Python

I am designing a simple Machine Learning program. I would like to calculate the total number of positive examples for a nested decision tree table. I'm running into an issue with incrementing the variable p and n in my entropy function

import json

decisionTreeTable = {
    "example1": {
        "attributes": {
            "alt": True,
            "Bar": False,
            "Fri": True,
            "Hun": True,
            "Pat": "SOME",
            "Price": "$$$",
            "Rain": False,
            "Res": True,
            "Type": "FRENCH",
            "Est": "1-10",
            "WillWait": True
        }
    },
    "example2": {
        "attributes": {
            "alt": True,
            "Bar": False,
            "Fri": True,
            "Hun": True,
            "Pat": "FULL",
            "Price": "$",
            "Rain": False,
            "Res": False,
            "Type": "THAI",
            "Est": "30-60",
            "WillWait": False
        }
    },
    "example3": {
        "attributes": {
            "alt": False,
            "Bar": True,
            "Fri": False,
            "Hun": False,
            "Pat": "SOME",
            "Price": "$",
            "Rain": False,
            "Res": False,
            "Type": "BURGER",
            "Est": "0-10",
            "WillWait": True
        }
    }
}

def recursivelyCalculatePositiveAndNegativeExamples(p,n,decisionTreeTable):
    for key, value in decisionTreeTable.items():
        if type(value) is dict:
            recursivelyCalculatePositiveAndNegativeExamples(p,n,value)
        else:
            if key == "WillWait" and value:
                print(key,":",value)
                p += 1
            elif key == "WillWait":
                print(key,":",value)
                n += 1

def entropy(decisionTreeTable):
    print("Calculating entropy for example set")
    p = 0
    n = 0
    recursivelyCalculatePositiveAndNegativeExamples(p,n,decisionTreeTable)
    print("Total number of positive examples p", ":", p)
    print("Total number of negative examples n", ":", n)

entropy(decisionTreeTable)

When I run this program they always come back as 0. I believe this is a simple issue. If anyone can help me I would greatly appreciate it.

Upvotes: 0

Views: 73

Answers (3)

The problem is that there are no return values in your function.

Try these changes:

def recursivelyCalculatePositiveAndNegativeExamples(p,n,decisionTreeTable):
    for key, value in decisionTreeTable.items():
        if type(value) is dict:
            p,n=recursivelyCalculatePositiveAndNegativeExamples(p,n,value)
        else:
            if key == "WillWait" and value:
                print(key,":",value)
                p += 1
            elif key == "WillWait":
                print(key,":",value)
                n += 1
    return p,n

def entropy(decisionTreeTable):
    print("Calculating entropy for example set")
    p = 0
    n = 0
    p,n=recursivelyCalculatePositiveAndNegativeExamples(p,n,decisionTreeTable)
    print("Total number of positive examples p", ":", p)
    print("Total number of negative examples n", ":", n)

Now entropy(decisionTreeTable) gives:

Calculating entropy for example set
WillWait : True
WillWait : False
WillWait : True
Total number of positive examples p : 2
Total number of negative examples n : 1 

Upvotes: 0

Serial Lazer
Serial Lazer

Reputation: 1669

You need to return the values to keep track of them in Python.

Having made the minor fix, now your code works:

import json

decisionTreeTable = {
    "example1": {
        "attributes": {
            "alt": True,
            "Bar": False,
            "Fri": True,
            "Hun": True,
            "Pat": "SOME",
            "Price": "$$$",
            "Rain": False,
            "Res": True,
            "Type": "FRENCH",
            "Est": "1-10",
            "WillWait": True
        }
    },
    "example2": {
        "attributes": {
            "alt": True,
            "Bar": False,
            "Fri": True,
            "Hun": True,
            "Pat": "FULL",
            "Price": "$",
            "Rain": False,
            "Res": False,
            "Type": "THAI",
            "Est": "30-60",
            "WillWait": False
        }
    },
    "example3": {
        "attributes": {
            "alt": False,
            "Bar": True,
            "Fri": False,
            "Hun": False,
            "Pat": "SOME",
            "Price": "$",
            "Rain": False,
            "Res": False,
            "Type": "BURGER",
            "Est": "0-10",
            "WillWait": True
        }
    }
}

def recursivelyCalculatePositiveAndNegativeExamples(p,n,decisionTreeTable):
    print(p, n)
    for key, value in decisionTreeTable.items():
        if type(value) is dict:
            _p, _n = recursivelyCalculatePositiveAndNegativeExamples(p,n,value)
            p += _p
            n += _n
        else:
            if key == "WillWait" and value:
                print(key,":",value)
                p += 1
            elif key == "WillWait":
                print(key,":",value)
                n += 1
    return p, n


def entropy(decisionTreeTable):
    print("Calculating entropy for example set")
    p = 0
    n = 0
    p, n = recursivelyCalculatePositiveAndNegativeExamples(p,n,decisionTreeTable)
    print("Total number of positive examples p", ":", p)
    print("Total number of negative examples n", ":", n)

entropy(decisionTreeTable)

Output:

Calculating entropy for example set
0 0
0 0
0 0
WillWait : True
1 0
1 0
WillWait : False
3 1
3 1
WillWait : True
Total number of positive examples p : 10
Total number of negative examples n : 3

Upvotes: 1

Dani Mesejo
Dani Mesejo

Reputation: 61910

Instead of relying on modifying global values (or arguments), make the function return p and n:

def recursively_calculate_positive_and_negative_examples(dt):
    p, n = 0, 0
    for key, value in dt.items():
        if isinstance(value, dict):
            pi, ni = recursively_calculate_positive_and_negative_examples(value)
            p += pi
            n += ni
        elif key == "WillWait":
            p += int(value)
            n += int(not value)
    return p, n


result = recursively_calculate_positive_and_negative_examples(decisionTreeTable)
print(result)

Output

(2, 1)

Upvotes: 2

Related Questions