Skip to content

Commit 5cb9fe9

Browse files
committed
load module for after python 3.11
1 parent fd0d0dd commit 5cb9fe9

File tree

8 files changed

+59
-39
lines changed

8 files changed

+59
-39
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ prediction = chef.predict(model, param = ['Sunny', 'Hot', 'High', 'Weak'])
8585
You can consume built decision trees directly as well. In this way, you can restore already built decision trees and skip learning steps, or apply [transfer learning](https://youtu.be/9hX8ir7_ZtA). Loaded trees offer you findDecision method to test for new instances.
8686

8787
```python
88-
moduleName = "outputs/rules/rules" #this will load outputs/rules/rules.py
89-
tree = chef.restoreTree(moduleName)
88+
module_name = "outputs/rules/rules" #this will load outputs/rules/rules.py
89+
tree = chef.restoreTree(module_name)
9090
prediction = tree.findDecision(['Sunny', 'Hot', 'High', 'Weak'])
9191
```
9292

chefboost/Chefboost.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -443,16 +443,16 @@ def load_model(file_name: str = "model.pkl") -> dict:
443443
return model
444444

445445

446-
def restoreTree(moduleName) -> dict:
446+
def restoreTree(module_name) -> Any:
447447
"""
448448
Load built model from set of decision rules
449449
Args:
450-
moduleName (str): e.g. outputs/rules/rules to restore outputs/rules/rules.py
450+
module_name (str): e.g. outputs/rules/rules to restore outputs/rules/rules.py
451451
Returns:
452452
built model (dict)
453453
"""
454454

455-
return functions.restoreTree(moduleName)
455+
return functions.restoreTree(module_name)
456456

457457

458458
def feature_importance(rules: Union[str, list]) -> pd.DataFrame:

chefboost/commons/functions.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import pathlib
2-
import imp # pylint: disable=deprecated-module
32
import os
43
from os import path
54
import multiprocessing
65
from typing import Optional
76
import numpy as np
87
from chefboost import Chefboost as cb
98
from chefboost.commons.logger import Logger
9+
from chefboost.commons.module import load_module
1010

1111
# pylint: disable=no-else-return, broad-except
1212

@@ -23,9 +23,8 @@ def bulk_prediction(df, model):
2323
df["Prediction"] = predictions
2424

2525

26-
def restoreTree(moduleName):
27-
fp, pathname, description = imp.find_module(moduleName)
28-
return imp.load_module(moduleName, fp, pathname, description)
26+
def restoreTree(module_name):
27+
return load_module(module_name)
2928

3029

3130
def softmax(w):

chefboost/commons/module.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import sys
2+
from types import ModuleType
3+
4+
# pylint: disable=no-else-return
5+
6+
7+
def load_module(module_name: str) -> ModuleType:
8+
"""
9+
Load python module with its name
10+
Args:
11+
module_name (str): module name without .py extension
12+
Returns:
13+
module (ModuleType)
14+
"""
15+
if sys.version_info >= (3, 11):
16+
import importlib.util
17+
18+
spec = importlib.util.find_spec(module_name)
19+
if spec is None:
20+
raise ImportError(f"Module '{module_name}' not found")
21+
22+
module = importlib.util.module_from_spec(spec)
23+
spec.loader.exec_module(module)
24+
return module
25+
else:
26+
import imp # pylint: disable=deprecated-module
27+
28+
fp, pathname, description = imp.find_module(module_name)
29+
return imp.load_module(module_name, fp, pathname, description)

chefboost/training/Training.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import math
2-
import imp # pylint:disable=deprecated-module
32
import uuid
43
import json
54
import copy
@@ -15,6 +14,7 @@
1514
from chefboost.training import Preprocess
1615
from chefboost.commons import functions
1716
from chefboost.commons.logger import Logger
17+
from chefboost.commons.module import load_module
1818

1919
# pylint: disable=too-many-function-args, unused-argument
2020

@@ -668,9 +668,8 @@ def buildDecisionTree(
668668
):
669669
# this is reguler decision tree. find accuracy here.
670670

671-
moduleName = "outputs/rules/rules"
672-
fp, pathname, description = imp.find_module(moduleName)
673-
myrules = imp.load_module(moduleName, fp, pathname, description) # rules0
671+
module_name = "outputs/rules/rules"
672+
myrules = load_module(module_name) # rules0
674673
models.append(myrules)
675674

676675
return models
@@ -682,9 +681,8 @@ def findPrediction(row):
682681
for j in range(0, num_of_features):
683682
params.append(row[j])
684683

685-
moduleName = "outputs/rules/rules"
686-
fp, pathname, description = imp.find_module(moduleName)
687-
myrules = imp.load_module(moduleName, fp, pathname, description) # rules0
684+
module_name = "outputs/rules/rules"
685+
myrules = load_module(module_name) # rules0
688686

689687
prediction = myrules.findDecision(params)
690688
return prediction

chefboost/tuning/adaboost.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import imp # pylint: disable=deprecated-module
21
import math
32

43
import pandas as pd
@@ -8,6 +7,7 @@
87
from chefboost.commons import functions
98
from chefboost.training import Training
109
from chefboost.commons.logger import Logger
10+
from chefboost.commons.module import load_module
1111

1212
# pylint: disable=unused-argument
1313

@@ -23,9 +23,8 @@ def findPrediction(row):
2323
for j in range(0, columns - 1):
2424
params.append(row[j])
2525

26-
moduleName = f"outputs/rules/rules_{int(epoch)}"
27-
fp, pathname, description = imp.find_module(moduleName)
28-
myrules = imp.load_module(moduleName, fp, pathname, description)
26+
module_name = f"outputs/rules/rules_{int(epoch)}"
27+
myrules = load_module(module_name)
2928

3029
prediction = functions.sign(myrules.findDecision(params))
3130

@@ -79,9 +78,8 @@ def apply(df, config, header, dataset_features, validation_df=None, process_id=N
7978

8079
# ---------------------------------------
8180

82-
moduleName = "outputs/rules/rules_" + str(i)
83-
fp, pathname, description = imp.find_module(moduleName)
84-
myrules = imp.load_module(moduleName, fp, pathname, description)
81+
module_name = "outputs/rules/rules_" + str(i)
82+
myrules = load_module(module_name)
8583
models.append(myrules)
8684

8785
# ---------------------------------------

chefboost/tuning/gbm.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import imp # pylint: disable=deprecated-module
21
import gc
32

43
import pandas as pd
@@ -8,6 +7,7 @@
87
from chefboost.commons import functions
98
from chefboost.training import Training
109
from chefboost.commons.logger import Logger
10+
from chefboost.commons.module import load_module
1111

1212
# pylint: disable=unused-argument
1313

@@ -23,9 +23,8 @@ def findPrediction(row):
2323
for j in range(0, columns - 1):
2424
params.append(row[j])
2525

26-
moduleName = f"outputs/rules/rules{epoch - 1}"
27-
fp, pathname, description = imp.find_module(moduleName)
28-
myrules = imp.load_module(moduleName, fp, pathname, description)
26+
module_name = f"outputs/rules/rules{epoch - 1}"
27+
myrules = load_module(module_name)
2928

3029
# prediction = int(myrules.findDecision(params))
3130
prediction = myrules.findDecision(params)
@@ -81,9 +80,8 @@ def regressor(df, config, header, dataset_features, validation_df=None, process_
8180
# run data(i-1) and rules(i-1), save data1
8281

8382
# dynamic import
84-
moduleName = f"outputs/rules/rules{index - 1}"
85-
fp, pathname, description = imp.find_module(moduleName)
86-
myrules = imp.load_module(moduleName, fp, pathname, description) # rules0
83+
module_name = f"outputs/rules/rules{index - 1}"
84+
myrules = load_module(module_name) # rules0
8785

8886
models.append(myrules)
8987

@@ -237,9 +235,8 @@ def classifier(df, config, header, dataset_features, validation_df=None, process
237235
# ----------------------------
238236

239237
# dynamic import
240-
moduleName = "outputs/rules/rules-for-" + current_class + "-round-" + str(epoch)
241-
fp, pathname, description = imp.find_module(moduleName)
242-
myrules = imp.load_module(moduleName, fp, pathname, description) # rules0
238+
module_name = "outputs/rules/rules-for-" + current_class + "-round-" + str(epoch)
239+
myrules = load_module(module_name) # rules0
243240

244241
models.append(myrules)
245242

chefboost/tuning/randomforest.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import multiprocessing
22
from contextlib import closing
3-
import imp # pylint: disable=deprecated-module
43

54
from tqdm import tqdm
65

76
from chefboost.commons import functions
87
from chefboost.training import Training
8+
from chefboost.commons.module import load_module
99

1010
# pylint: disable=unused-argument
1111

@@ -31,8 +31,8 @@ def apply(df, config, header, dataset_features, validation_df=None, process_id=N
3131

3232
root = 1
3333

34-
moduleName = "outputs/rules/rule_" + str(i)
35-
file = moduleName + ".py"
34+
module_name = "outputs/rules/rule_" + str(i)
35+
file = module_name + ".py"
3636

3737
functions.createFile(file, header)
3838

@@ -85,9 +85,8 @@ def apply(df, config, header, dataset_features, validation_df=None, process_id=N
8585
# -------------------------------
8686
# collect models for both serial and parallel here
8787
for i in range(0, num_of_trees):
88-
moduleName = "outputs/rules/rule_" + str(i)
89-
fp, pathname, description = imp.find_module(moduleName)
90-
myrules = imp.load_module(moduleName, fp, pathname, description)
88+
module_name = "outputs/rules/rule_" + str(i)
89+
myrules = load_module(module_name)
9190
models.append(myrules)
9291

9392
# -------------------------------

0 commit comments

Comments
 (0)