0

I'm learning machine learning from this tutorial on Kaggle.

I try to modify the project structure so I create a new .py file to create a new class. This is the class :

class ModelHelper(object):
    def __init__(self, model, seed=0, params=None):
        params['random_state'] = seed # TypeError: 'NoneType' object does not support item assignment
        self.model = model(**params)

    def train(self, x_train, y_train):
        self.model.fit(x_train, y_train)

    def predict(self, x):
        return self.model.predict(x)

    def fit(self, x, y):
        return self.model.fit(x, y)

    def feature_importances(self, x, y):
        print(self.model.fit(x, y).feature_importances_)

And this is how i used it :

from helper import ModelHelper

log_reg = ModelHelper(model=LogisticRegression);

This is the full error that I got :

Traceback (most recent call last):
  File "F:/backup/PycharmProjects/KaggleTitanic/DataAnalysis.py", line 191, in <module>
    log_reg = ModelHelper(model=LogisticRegression);
  File "F:\backup\PycharmProjects\KaggleTitanic\ModelHelper.py", line 3, in __init__
    params['random_state'] = seed # TypeError: 'NoneType' object does not support item assignment
TypeError: 'NoneType' object does not support item assignment

Probably the error caused by params=None in my __init__ parameter. What I want is to make this params field optional (I don’t have to pass it if I don’t want to)

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Blaze Tama
  • 10,828
  • 13
  • 69
  • 129
  • you should define param as `dict` like `def __init__(self, model, seed=0, params={})` – akash karothiya Sep 29 '17 at 06:36
  • @akashkarothiya that would be A Bad Idea: https://stackoverflow.com/q/1132941/3001761. Perhaps change it to `**params` instead, then you can pass arbitrary keyword parameters instead of a dictionary. Or just start with `params = params or {}`. – jonrsharpe Sep 29 '17 at 06:39
  • ah, I almost forgot this, thanks @jonrsharpe – akash karothiya Sep 29 '17 at 06:40
  • 1
    What is the `__init__` supposed to do when you don't provide a `params`? You need to test for `None`, and do something intelligent with the result. – hpaulj Sep 29 '17 at 06:40
  • `def __init__(self, model, seed=0, **params):` @jonrsharpe is this seems ok ? thing is I am also in learning phase, interacting with mentors like you is special to us. – akash karothiya Sep 29 '17 at 06:41

1 Answers1

1

Modify ModelHelper so that it properly initializes a default for params if a value is not passed.

class ModelHelper(object):
    def __init__(self, model, seed=0, params=None):
        if params is None:
            params = {}
        params['random_state'] = seed # TypeError: 'NoneType' object does not support item assignment
        self.model = model(**params)

    def train(self, x_train, y_train):
        self.model.fit(x_train, y_train)

    def predict(self, x):
        return self.model.predict(x)

    def fit(self, x, y):
        return self.model.fit(x, y)

    def feature_importances(self, x, y):
        print(self.model.fit(x, y).feature_importances_)

It is necessary to use params=None and not params={} in the call signature, so that each instance of ModelHelper uses its own separate params dictionary. It is also possible to do this by changing the call signature to use **params, but I suggested the answer above in the interest of not breaking any code you may already have written that calls with this signature.

Jeremy McGibbon
  • 3,527
  • 14
  • 22