Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: 'dict_items' object is not subscriptable on running if statement to shortlist items

I am using a function below to run the apriori algorithm and calculate support, confidence for all itemsets. The function uses a dictionary object to store all values of items and their corresponding support, confidence.

After running the if statement to select items having minimum support value of 0.15 and confidence of 0.6, I am getting an error below that dict_items object is not subscriptable.

for key, value in largeSet.items()[1:]:

TypeError: 'dict_items' object is not subscriptable



def runApriori(data_iter, minSupport, minConfidence):
    """
    run the apriori algorithm. data_iter is a record iterator
    Return both:
     - items (tuple, support)
     - rules ((pretuple, posttuple), confidence)
    """
    itemSet, transactionList = getItemSetTransactionList(data_iter)

    freqSet = defaultdict(int)
    largeSet = dict()
    # Global dictionary which stores (key=n-itemSets,value=support)
    # which satisfy minSupport

    assocRules = dict()
    # Dictionary which stores Association Rules

    oneCSet = returnItemsWithMinSupport(itemSet,
                                        transactionList,
                                        minSupport,
                                        freqSet)

    currentLSet = oneCSet
    k = 2
    while(currentLSet != set([])):
        largeSet[k-1] = currentLSet
        currentLSet = joinSet(currentLSet, k)
        currentCSet = returnItemsWithMinSupport(currentLSet,
                                                transactionList,
                                                minSupport,
                                                freqSet)
        currentLSet = currentCSet
        k = k + 1

    def getSupport(item):
            """local function which Returns the support of an item"""
            return float(freqSet[item])/len(transactionList)

    toRetItems = []
    for key, value in largeSet.items():
        toRetItems.extend([(tuple(item), getSupport(item))
                           for item in value])

    toRetRules = []
    for key, value in largeSet.items()[1:]:
        for item in value:
            _subsets = map(frozenset, [x for x in subsets(item)])
            for element in _subsets:
                remain = item.difference(element)
                if len(remain) > 0:
                    confidence = getSupport(item)/getSupport(element)
                    if confidence >= minConfidence:
                        toRetRules.append(((tuple(element), tuple(remain)),
                                           confidence))
    return toRetItems, toRetRules

if __name__ == "__main__":
    inFile = ''
    minSupport = 0.15
    minConfidence = 0.6

    items, rules = runApriori(inFile, minSupport, minConfidence)

    printResults(items, rules) 
like image 430
K Bh Avatar asked Sep 18 '18 15:09

K Bh


2 Answers

Prior to CPython 3.6 (and 3.7 for any Python interpreter), dicts have no reliable ordering, so assuming the first item is the one you want to skip is a bad idea.

That said, if you're on 3.6+, and you know you want to skip the first element, you can use itertools.islice to do this safely, changing:

for key, value in largeSet.items()[1:]:

to:

# At top of file
from itertools import islice

for key, value in islice(largeSet.items(), 1, None):    
like image 99
ShadowRanger Avatar answered Sep 23 '22 02:09

ShadowRanger


You're not supposed to be relying on dictionaries having a particular order, so python doesn't let you skip the "first" item in a dictionary, since what is "first" depends on there being a particular order. You can cast it as a list: for key, value in list(largeSet.items())[1:], but that would rely on the dictionary order being what you expect it would be. Better would to just do for key, value in largeSet.items()), then check within the loop whether it's the item you don't want to operate on, and continue if it is. Or use pandas series.

like image 43
Acccumulation Avatar answered Sep 24 '22 02:09

Acccumulation