rulelearn-ripper-interactive 0.2.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. rulelearn_ri/__init__.py +6 -0
  2. rulelearn_ri/algorithms/__init__.py +0 -0
  3. rulelearn_ri/algorithms/r2n/__init__.py +0 -0
  4. rulelearn_ri/algorithms/r2n/base.py +28 -0
  5. rulelearn_ri/algorithms/r2n/functions.py +25 -0
  6. rulelearn_ri/algorithms/r2n/mask.py +58 -0
  7. rulelearn_ri/algorithms/r2n/preprocessing_layers.py +192 -0
  8. rulelearn_ri/algorithms/r2n/r2n_algo.py +287 -0
  9. rulelearn_ri/algorithms/r2n/simple_rulenet.py +75 -0
  10. rulelearn_ri/algorithms/r2n/training.py +34 -0
  11. rulelearn_ri/algorithms/r2n/utilities.py +117 -0
  12. rulelearn_ri/algorithms/rbm/__init__.py +0 -0
  13. rulelearn_ri/algorithms/rbm/boolean_rule_cg.py +65 -0
  14. rulelearn_ri/algorithms/rbm/rbm/BRCG.py +69 -0
  15. rulelearn_ri/algorithms/rbm/rbm/GLRM.py +98 -0
  16. rulelearn_ri/algorithms/rbm/rbm/__init__.py +6 -0
  17. rulelearn_ri/algorithms/rbm/rbm/beam_search.py +302 -0
  18. rulelearn_ri/algorithms/rbm/rbm/boolean_rule_cg.py +245 -0
  19. rulelearn_ri/algorithms/rbm/rbm/features.py +544 -0
  20. rulelearn_ri/algorithms/rbm/rbm/linear_regression.py +393 -0
  21. rulelearn_ri/algorithms/rbm/rbm/logistic_regression.py +447 -0
  22. rulelearn_ri/algorithms/rbm/utils.py +13 -0
  23. rulelearn_ri/algorithms/ripper/__init__.py +10 -0
  24. rulelearn_ri/algorithms/ripper/base.py +81 -0
  25. rulelearn_ri/algorithms/ripper/binding.py +541 -0
  26. rulelearn_ri/algorithms/ripper/mdl.py +97 -0
  27. rulelearn_ri/algorithms/ripper/pruning.py +212 -0
  28. rulelearn_ri/algorithms/ripper/ripper.py +600 -0
  29. rulelearn_ri/algorithms/ripper/ripper_ruleset_generator.py +26 -0
  30. rulelearn_ri/algorithms/ripper/single_rule.py +425 -0
  31. rulelearn_ri/dise.py +64 -0
  32. rulelearn_ri/trxf/__init__.py +0 -0
  33. rulelearn_ri/trxf/classifier/__init__.py +0 -0
  34. rulelearn_ri/trxf/classifier/ruleset_classifier.py +153 -0
  35. rulelearn_ri/trxf/core/__init__.py +5 -0
  36. rulelearn_ri/trxf/core/boolean_evaluator.py +15 -0
  37. rulelearn_ri/trxf/core/conjunction.py +50 -0
  38. rulelearn_ri/trxf/core/dnf_ruleset.py +64 -0
  39. rulelearn_ri/trxf/core/feature.py +155 -0
  40. rulelearn_ri/trxf/core/predicate.py +98 -0
  41. rulelearn_ri/trxf/core/ruleset_generator.py +25 -0
  42. rulelearn_ri/trxf/core/utils.py +40 -0
  43. rulelearn_ri/trxf/metrics.py +98 -0
  44. rulelearn_ri/trxf/pmml_export/__init__.py +4 -0
  45. rulelearn_ri/trxf/pmml_export/__version__.py +1 -0
  46. rulelearn_ri/trxf/pmml_export/models/__init__.py +24 -0
  47. rulelearn_ri/trxf/pmml_export/models/attribute.py +24 -0
  48. rulelearn_ri/trxf/pmml_export/models/characteristics.py +20 -0
  49. rulelearn_ri/trxf/pmml_export/models/data_dictionary.py +53 -0
  50. rulelearn_ri/trxf/pmml_export/models/mining_schema.py +25 -0
  51. rulelearn_ri/trxf/pmml_export/models/pmml_ruleset_model.py +16 -0
  52. rulelearn_ri/trxf/pmml_export/models/predicate.py +42 -0
  53. rulelearn_ri/trxf/pmml_export/models/rule.py +26 -0
  54. rulelearn_ri/trxf/pmml_export/models/ruleset.py +28 -0
  55. rulelearn_ri/trxf/pmml_export/models/ruleset_model.py +16 -0
  56. rulelearn_ri/trxf/pmml_export/models/scorecard.py +35 -0
  57. rulelearn_ri/trxf/pmml_export/pmml_exporter.py +18 -0
  58. rulelearn_ri/trxf/pmml_export/reader/__init__.py +2 -0
  59. rulelearn_ri/trxf/pmml_export/reader/abstract_reader.py +16 -0
  60. rulelearn_ri/trxf/pmml_export/reader/trxf_reader.py +113 -0
  61. rulelearn_ri/trxf/pmml_export/serializer/__init__.py +2 -0
  62. rulelearn_ri/trxf/pmml_export/serializer/abstract_serializer.py +11 -0
  63. rulelearn_ri/trxf/pmml_export/serializer/nyoka_serializer.py +162 -0
  64. rulelearn_ri/trxf/scorecard/__init__.py +3 -0
  65. rulelearn_ri/trxf/scorecard/bins.py +253 -0
  66. rulelearn_ri/trxf/scorecard/partition.py +71 -0
  67. rulelearn_ri/trxf/scorecard/scorecard.py +78 -0
  68. rulelearn_ripper_interactive-0.2.3.dist-info/METADATA +164 -0
  69. rulelearn_ripper_interactive-0.2.3.dist-info/RECORD +73 -0
  70. rulelearn_ripper_interactive-0.2.3.dist-info/WHEEL +5 -0
  71. rulelearn_ripper_interactive-0.2.3.dist-info/licenses/LICENSE +201 -0
  72. rulelearn_ripper_interactive-0.2.3.dist-info/licenses/NOTICE +11 -0
  73. rulelearn_ripper_interactive-0.2.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,25 @@
1
+ try:
2
+ # python >= 3.7
3
+ from dataclasses import dataclass as dataclass
4
+ from dataclasses import field as field
5
+ except ImportError:
6
+ from attr import s as dataclass
7
+ from attr import ib as field
8
+ import enum
9
+ import typing
10
+
11
+
12
+ class MiningFieldUsageType(enum.Enum):
13
+ active = 0
14
+ target = 1
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class MiningField:
19
+ name: str = field()
20
+ usageType: MiningFieldUsageType = field(default=MiningFieldUsageType.active)
21
+
22
+
23
+ @dataclass(frozen=True)
24
+ class MiningSchema:
25
+ miningFields: typing.List[MiningField] = field()
@@ -0,0 +1,16 @@
1
+ try:
2
+ # python >= 3.7
3
+ from dataclasses import dataclass as dataclass
4
+ from dataclasses import field as field
5
+ except ImportError:
6
+ from attr import s as dataclass
7
+ from attr import ib as field
8
+
9
+ from .data_dictionary import DataDictionary
10
+ from .ruleset_model import RuleSetModel
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class SimplePMMLRuleSetModel:
15
+ dataDictionary: DataDictionary = field()
16
+ ruleSetModel: RuleSetModel = field()
@@ -0,0 +1,42 @@
1
+ try:
2
+ # python >= 3.7
3
+ from dataclasses import dataclass as dataclass
4
+ from dataclasses import field as field
5
+ except ImportError:
6
+ from attr import s as dataclass
7
+ from attr import ib as field
8
+ import enum
9
+ import typing
10
+
11
+
12
+ class Operator(enum.Enum):
13
+ equal = 0
14
+ notEqual = 1
15
+ lessThan = 2
16
+ lessOrEqual = 3
17
+ greaterThan = 4
18
+ greaterOrEqual = 5
19
+ isMissing = 6
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class SimplePredicate:
24
+ operator: Operator = field()
25
+ field: str = field()
26
+ value: typing.Optional[str] = None
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class TruePredicate:
31
+ pass
32
+
33
+
34
+ # Use functional api to add aliases for `or` and `and`
35
+ BooleanOperator = enum.Enum('BooleanOperator',
36
+ [('or', 0), ('or_', 0), ('and', 1), ('and_', 1), ('xor', 2), ('surrogate', 3)])
37
+
38
+
39
+ @dataclass(frozen=True)
40
+ class CompoundPredicate:
41
+ simplePredicates: typing.List[SimplePredicate] = field()
42
+ booleanOperator: BooleanOperator = field()
@@ -0,0 +1,26 @@
1
+ try:
2
+ # python >= 3.7
3
+ from dataclasses import dataclass as dataclass
4
+ from dataclasses import field as field
5
+ except ImportError:
6
+ from attr import s as dataclass
7
+ from attr import ib as field
8
+ import typing
9
+
10
+ from .predicate import CompoundPredicate
11
+ from .predicate import SimplePredicate
12
+
13
+ DEFAULT_WEIGHT = 1.0
14
+ DEFAULT_CONFIDENCE = 1.0
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class SimpleRule:
19
+ predicate: typing.Union[SimplePredicate, CompoundPredicate] = field()
20
+ score: str = field()
21
+
22
+ id: typing.Optional[str] = field(default=None)
23
+ recordCount: typing.Optional[int] = field(default=None)
24
+ nbCorrect: typing.Optional[int] = field(default=None)
25
+ confidence: typing.Optional[float] = field(default=DEFAULT_CONFIDENCE)
26
+ weight: typing.Optional[float] = field(default=DEFAULT_WEIGHT)
@@ -0,0 +1,28 @@
1
+ try:
2
+ # python >= 3.7
3
+ from dataclasses import dataclass as dataclass
4
+ from dataclasses import field as field
5
+ except ImportError:
6
+ from attr import s as dataclass
7
+ from attr import ib as field
8
+ import enum
9
+ import typing
10
+
11
+ from .rule import SimpleRule
12
+
13
+
14
+ class RuleSelectionMethod(enum.Enum):
15
+ firstHit = 0
16
+ weightedMax = 1
17
+ weightedSum = 2
18
+
19
+
20
+ @dataclass(frozen=True)
21
+ class RuleSet:
22
+ ruleSelectionMethod: typing.List[RuleSelectionMethod] = field()
23
+ rules: typing.List[SimpleRule] = field()
24
+
25
+ recordCount: typing.Optional[int] = field(default=None)
26
+ nbCorrect: typing.Optional[int] = field(default=None)
27
+ defaultScore: typing.Optional[str] = field(default=None)
28
+ defaultConfidence: typing.Optional[float] = field(default=None)
@@ -0,0 +1,16 @@
1
+ try:
2
+ # python >= 3.7
3
+ from dataclasses import dataclass as dataclass
4
+ from dataclasses import field as field
5
+ except ImportError:
6
+ from attr import s as dataclass
7
+ from attr import ib as field
8
+
9
+ from .mining_schema import MiningSchema
10
+ from .ruleset import RuleSet
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class RuleSetModel:
15
+ miningSchema: MiningSchema = field()
16
+ ruleSet: RuleSet = field()
@@ -0,0 +1,35 @@
1
+ import typing
2
+
3
+ from . import characteristics
4
+ from . import data_dictionary
5
+ from . import mining_schema
6
+
7
+ try:
8
+ # python >= 3.7
9
+ from dataclasses import dataclass as dataclass
10
+ from dataclasses import field as field
11
+ except ImportError:
12
+ from attr import s as dataclass
13
+ from attr import ib as field
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class OutputField:
18
+ name: str
19
+ feature: str
20
+ dataType: data_dictionary.DataType
21
+ optype: data_dictionary.OpType
22
+
23
+
24
+ @dataclass(frozen=True)
25
+ class Output:
26
+ outputFields: typing.List[OutputField]
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class Scorecard:
31
+ dataDictionary: data_dictionary.DataDictionary
32
+ miningSchema: mining_schema.MiningSchema
33
+ output: Output
34
+ characteristics: characteristics.Characteristics
35
+ initialScore: str = field(default="0")
@@ -0,0 +1,18 @@
1
+ from rulelearn_ri.trxf.classifier.ruleset_classifier import RuleSetClassifier
2
+ from rulelearn_ri.trxf.pmml_export import AbstractSerializer, AbstractReader
3
+
4
+
5
+ class PmmlExporter:
6
+ def __init__(self, reader: AbstractReader, serializer: AbstractSerializer):
7
+ self._serializer = serializer
8
+ self._reader = reader
9
+
10
+ def export(self, trxf_classifier: RuleSetClassifier):
11
+ """
12
+ Translate a given TRXF RuleSetClassifier to a PMML string
13
+ @param trxf_classifier: A TRXF RuleSetClassifier
14
+ @return: The corresponding PMML string
15
+ """
16
+ if self._reader.data_dictionary is None:
17
+ raise AssertionError("Missing data dictionary in reader object")
18
+ return self._serializer.serialize(self._reader.read(trxf_classifier))
@@ -0,0 +1,2 @@
1
+ from .abstract_reader import AbstractReader
2
+ from .trxf_reader import TrxfReader
@@ -0,0 +1,16 @@
1
+ import abc
2
+ import typing
3
+
4
+ from .. import models
5
+
6
+
7
+ class AbstractReader(abc.ABC):
8
+ T = typing.TypeVar('T')
9
+
10
+ @property
11
+ def data_dictionary(self):
12
+ raise NotImplementedError
13
+
14
+ @abc.abstractmethod
15
+ def read(self, model: T) -> models.SimplePMMLRuleSetModel:
16
+ raise NotImplementedError
@@ -0,0 +1,113 @@
1
+ from typing import Dict
2
+
3
+ import pandas as pd
4
+ from pandas.api.types import is_bool_dtype, is_float_dtype, is_integer_dtype
5
+
6
+ from rulelearn_ri.trxf.classifier import ruleset_classifier
7
+ from rulelearn_ri.trxf.classifier.ruleset_classifier import RuleSetClassifier
8
+ from rulelearn_ri.trxf.core import Conjunction, Relation
9
+ from rulelearn_ri.trxf.pmml_export import models
10
+ from rulelearn_ri.trxf.pmml_export.models.data_dictionary import Value
11
+ from rulelearn_ri.trxf.pmml_export.reader import AbstractReader
12
+ from rulelearn_ri.trxf.pmml_export.models import SimplePredicate, Operator, CompoundPredicate, \
13
+ BooleanOperator
14
+
15
+
16
+ class TrxfReader(AbstractReader):
17
+ def __init__(self, data_dictionary=None):
18
+ self._data_dictionary = data_dictionary
19
+
20
+ @property
21
+ def data_dictionary(self):
22
+ return self._data_dictionary
23
+
24
+ def read(self, trxf_classifier: RuleSetClassifier) -> models.SimplePMMLRuleSetModel:
25
+ """
26
+ Translate a TRXF RuleSetClassifier to an internal SimplePMMLRuleSetModel
27
+ """
28
+ trxf_to_pmml_rule_selection_map = {
29
+ ruleset_classifier.RuleSelectionMethod.FIRST_HIT: models.RuleSelectionMethod.firstHit,
30
+ ruleset_classifier.RuleSelectionMethod.WEIGHTED_SUM: models.RuleSelectionMethod.weightedSum,
31
+ ruleset_classifier.RuleSelectionMethod.WEIGHTED_MAX: models.RuleSelectionMethod.weightedMax
32
+ }
33
+ trxf_rules = trxf_classifier.rules
34
+ mining_schema = _extract_mining_schema(trxf_rules)
35
+ simple_rules = _convert_to_simple_rules(trxf_rules)
36
+ ruleset = models.RuleSet(
37
+ ruleSelectionMethod=[trxf_to_pmml_rule_selection_map[trxf_classifier.rule_selection_method]],
38
+ rules=simple_rules,
39
+ defaultScore=str(trxf_classifier.default_label))
40
+ rule_set_model = models.RuleSetModel(miningSchema=mining_schema, ruleSet=ruleset)
41
+ assert self._data_dictionary is not None
42
+ return models.SimplePMMLRuleSetModel(dataDictionary=self._data_dictionary, ruleSetModel=rule_set_model)
43
+
44
+ def load_data_dictionary(self, X: pd.DataFrame, values: Dict = None):
45
+ """
46
+ Extract the data dictionary from a feature dataframe, and store it
47
+
48
+ @param X: Input dataframe
49
+ @param values: A dict mapping column name to a list of possible categorical values. It will be inferred from X if not provided.
50
+ """
51
+ dtypes = X.dtypes
52
+ data_fields = []
53
+ for index, value in dtypes.items():
54
+ vals = None
55
+ # pandas dtype predicates also handle extension dtypes (e.g. the pandas 3 default StringDtype),
56
+ # which np.issubdtype cannot interpret
57
+ if is_bool_dtype(value):
58
+ data_type = models.DataType.boolean
59
+ op_type = models.OpType.categorical
60
+ elif is_integer_dtype(value):
61
+ data_type = models.DataType.integer
62
+ op_type = models.OpType.ordinal
63
+ elif is_float_dtype(value):
64
+ data_type = models.DataType.double if value.itemsize == 8 else models.DataType.float
65
+ op_type = models.OpType.continuous
66
+ else:
67
+ data_type = models.DataType.string
68
+ op_type = models.OpType.categorical
69
+ vals = values[index] if values is not None and index in values else list(X[index].unique())
70
+ wrapped_vals = list(map(lambda v: Value(v), vals)) if vals is not None else vals
71
+ data_fields.append(
72
+ models.DataField(name=str(index), optype=op_type, dataType=data_type, values=wrapped_vals))
73
+ self._data_dictionary = models.DataDictionary(data_fields)
74
+
75
+
76
+ def _convert_to_simple_rules(trxf_rules):
77
+ simple_rules = []
78
+ for rule in trxf_rules:
79
+ predicate = _convert_to_pmml_predicate(rule.conjunction)
80
+ confidence = rule.confidence if rule.confidence is not None else models.DEFAULT_CONFIDENCE
81
+ weight = rule.weight if rule.weight is not None else models.DEFAULT_WEIGHT
82
+ simple_rule = models.SimpleRule(predicate=predicate, score=str(rule.label), id=str(rule.conjunction),
83
+ recordCount=rule.record_count,
84
+ nbCorrect=rule.nb_correct, confidence=confidence, weight=weight)
85
+ simple_rules.append(simple_rule)
86
+ return simple_rules
87
+
88
+
89
+ def _convert_to_pmml_predicate(trxf_conjunction: Conjunction):
90
+ trxf_to_pmml_op = {
91
+ Relation.EQ: Operator.equal,
92
+ Relation.NEQ: Operator.notEqual,
93
+ Relation.LT: Operator.lessThan,
94
+ Relation.LE: Operator.lessOrEqual,
95
+ Relation.GT: Operator.greaterThan,
96
+ Relation.GE: Operator.greaterOrEqual
97
+ }
98
+ simple_predicates = [SimplePredicate(operator=trxf_to_pmml_op[trxf_predicate.relation],
99
+ value=str(trxf_predicate.value),
100
+ field=str(trxf_predicate.feature.variable_names[0]))
101
+ for trxf_predicate in trxf_conjunction.predicates]
102
+ return CompoundPredicate(simplePredicates=simple_predicates, booleanOperator=BooleanOperator.and_)
103
+
104
+
105
+ def _extract_mining_schema(trxf_rules):
106
+ mining_fields = {}
107
+ for rule in trxf_rules:
108
+ for predicate in rule.conjunction.predicates:
109
+ name = predicate.feature.variable_names[0]
110
+ if name not in mining_fields:
111
+ mining_field = models.MiningField(name=name)
112
+ mining_fields[name] = mining_field
113
+ return models.MiningSchema(miningFields=list(mining_fields.values()))
@@ -0,0 +1,2 @@
1
+ from .abstract_serializer import AbstractSerializer
2
+ from .nyoka_serializer import NyokaSerializer
@@ -0,0 +1,11 @@
1
+ import abc
2
+ import typing
3
+
4
+ from .. import models
5
+
6
+
7
+ class AbstractSerializer(abc.ABC):
8
+
9
+ @abc.abstractmethod
10
+ def serialize(self, model: typing.Union[models.SimplePMMLRuleSetModel, models.Scorecard]) -> str:
11
+ raise NotImplementedError
@@ -0,0 +1,162 @@
1
+ import typing
2
+ import datetime
3
+ import io
4
+
5
+ import nyoka.PMML44 as nyoka_pmml # noqa
6
+ import nyoka.base.constants as nyoka_constants
7
+
8
+ from .abstract_serializer import AbstractSerializer
9
+ from .. import __version__ as version
10
+ from .. import models as models
11
+
12
+
13
+ class NyokaSerializer(AbstractSerializer):
14
+ APPLICATION_NAME = 'SimpleRuleSetExport'
15
+ COPYRIGHT_STRING = 'Copyright IBM Corp'
16
+
17
+ def __init__(self, timestamp: datetime = None):
18
+ self._timestamp = timestamp
19
+
20
+ def serialize(self, model: typing.Union[models.SimplePMMLRuleSetModel, models.Scorecard]) -> str:
21
+ if isinstance(model, models.SimplePMMLRuleSetModel):
22
+ pmml_model = self._nyoka_pmml_model(
23
+ model,
24
+ RuleSetModel=None if model.ruleSetModel is None else [self._nyoka_rule_set_model(model.ruleSetModel)])
25
+ elif isinstance(model, models.Scorecard):
26
+ pmml_model = self._nyoka_pmml_model(
27
+ model,
28
+ Scorecard=None if model is None else [self._nyoka_scorecard_model(model)])
29
+ else:
30
+ raise NotImplemented
31
+ string_io = io.StringIO()
32
+ pmml_model.export(outfile=string_io, level=0)
33
+ return string_io.getvalue()
34
+
35
+ def _nyoka_pmml_model(
36
+ self,
37
+ model: typing.Union[models.SimplePMMLRuleSetModel, models.Scorecard],
38
+ **build_args
39
+ ) -> nyoka_pmml.PMML:
40
+ return nyoka_pmml.PMML(
41
+ version=nyoka_constants.PMML_SCHEMA.VERSION,
42
+ Header=nyoka_pmml.Header(
43
+ copyright=NyokaSerializer.COPYRIGHT_STRING,
44
+ description=nyoka_constants.HEADER_INFO.DEFAULT_DESCRIPTION,
45
+ Timestamp=nyoka_pmml.Timestamp(datetime.datetime.now() if self._timestamp is None else self._timestamp),
46
+ Application=nyoka_pmml.Application(name=NyokaSerializer.APPLICATION_NAME, version=version.version)),
47
+ DataDictionary=None if model.dataDictionary is None else self._nyoka_data_dictionary(model.dataDictionary),
48
+ **build_args)
49
+
50
+ def _nyoka_data_dictionary(self, data_dictionary: models.DataDictionary) -> nyoka_pmml.DataDictionary:
51
+ return nyoka_pmml.DataDictionary(
52
+ numberOfFields=0 if not data_dictionary.dataFields else len(data_dictionary.dataFields),
53
+ DataField=None if not data_dictionary.dataFields else [
54
+ self._nyoka_data_field(f) for f in data_dictionary.dataFields])
55
+
56
+ def _nyoka_data_field(self, data_field: models.DataField) -> nyoka_pmml.DataField:
57
+ return nyoka_pmml.DataField(
58
+ name=data_field.name,
59
+ optype=data_field.optype.name,
60
+ dataType=data_field.dataType.name,
61
+ Value=None if not data_field.values else [
62
+ nyoka_pmml.Value(value=val.value, property=val.property.name) for val in data_field.values])
63
+
64
+ def _nyoka_rule_set_model(self, rule_set_model: models.RuleSetModel) -> nyoka_pmml.RuleSetModel:
65
+ return nyoka_pmml.RuleSetModel(
66
+ functionName='classification',
67
+ algorithmName='RuleSet',
68
+ MiningSchema=None if rule_set_model.miningSchema is None else self._nyoka_mining_schema(
69
+ rule_set_model.miningSchema),
70
+ RuleSet=None if rule_set_model.ruleSet is None else self._nyoka_rule_set(rule_set_model.ruleSet))
71
+
72
+ def _nyoka_mining_schema(self, mining_schema: models.MiningSchema) -> nyoka_pmml.MiningSchema:
73
+ return nyoka_pmml.MiningSchema(
74
+ MiningField=[
75
+ nyoka_pmml.MiningField(name=f.name, usageType=f.usageType.name)
76
+ for f in mining_schema.miningFields])
77
+
78
+ def _nyoka_rule_set(self, rule_set: models.RuleSet) -> nyoka_pmml.RuleSet:
79
+ return nyoka_pmml.RuleSet(
80
+ RuleSelectionMethod=None if rule_set.ruleSelectionMethod is None else [
81
+ nyoka_pmml.RuleSelectionMethod(criterion=m.name)
82
+ for m in rule_set.ruleSelectionMethod],
83
+ SimpleRule=None if rule_set.rules is None else [self._nyoka_rule(r) for r in rule_set.rules],
84
+ recordCount=rule_set.recordCount,
85
+ nbCorrect=rule_set.nbCorrect,
86
+ defaultScore=rule_set.defaultScore,
87
+ defaultConfidence=rule_set.defaultConfidence)
88
+
89
+ def _nyoka_rule(self, simple_rule: models.SimpleRule) -> nyoka_pmml.SimpleRule:
90
+ return nyoka_pmml.SimpleRule(
91
+ SimplePredicate=None if (
92
+ simple_rule.predicate is None or not isinstance(simple_rule.predicate, models.SimplePredicate)) else
93
+ nyoka_pmml.SimplePredicate(
94
+ field=simple_rule.predicate.field,
95
+ operator=simple_rule.predicate.operator.name,
96
+ value=simple_rule.predicate.value),
97
+ CompoundPredicate=None if (
98
+ simple_rule.predicate is None or not isinstance(simple_rule.predicate,
99
+ models.CompoundPredicate)) else
100
+ nyoka_pmml.CompoundPredicate(
101
+ booleanOperator=simple_rule.predicate.booleanOperator.name,
102
+ SimplePredicate=[
103
+ nyoka_pmml.SimplePredicate(field=sp.field, operator=sp.operator.name, value=sp.value)
104
+ for sp in simple_rule.predicate.simplePredicates]),
105
+ score=simple_rule.score,
106
+ id=simple_rule.id,
107
+ recordCount=simple_rule.recordCount,
108
+ nbCorrect=simple_rule.nbCorrect,
109
+ confidence=simple_rule.confidence,
110
+ weight=simple_rule.weight)
111
+
112
+ def _nyoka_scorecard_model(self, scorecard: models.Scorecard) -> nyoka_pmml.Scorecard:
113
+ return nyoka_pmml.Scorecard(
114
+ functionName='regression',
115
+ algorithmName='ScoreCard',
116
+ MiningSchema=None if scorecard.miningSchema is None else self._nyoka_mining_schema(
117
+ scorecard.miningSchema),
118
+ initialScore=scorecard.initialScore,
119
+ useReasonCodes="false",
120
+ Output=None if scorecard.output is None else nyoka_pmml.Output(
121
+ OutputField=[
122
+ nyoka_pmml.OutputField(
123
+ name=outputField.name,
124
+ feature=outputField.feature,
125
+ dataType=outputField.dataType.name,
126
+ optype=outputField.optype.name) for outputField in scorecard.output.outputFields]),
127
+ Characteristics=None if scorecard.characteristics is None else self._nyoka_pmml_characteristics(
128
+ scorecard.characteristics))
129
+
130
+ def _nyoka_pmml_characteristics(self, characteristics: models.Characteristics) -> nyoka_pmml.Characteristics:
131
+ return nyoka_pmml.Characteristics(
132
+ Characteristic=[
133
+ nyoka_pmml.Characteristic(
134
+ name=characteristic.name,
135
+ Attribute=[self._nyoka_pmml_attributes(attribute) for attribute in characteristic.attributes])
136
+ for characteristic in characteristics.characteristics])
137
+
138
+ def _nyoka_pmml_attributes(self, attribute: models.Attribute) -> nyoka_pmml.Attribute:
139
+ return nyoka_pmml.Attribute(
140
+ partialScore=attribute.score if not isinstance(attribute.score, models.ComplexPartialScore) else None,
141
+ ComplexPartialScore=nyoka_pmml.ComplexPartialScore(
142
+ Apply=nyoka_pmml.Apply(
143
+ function='+',
144
+ Apply_member=[nyoka_pmml.Apply(
145
+ function='*',
146
+ FieldRef=[nyoka_pmml.FieldRef(field=attribute.score.feature_name)],
147
+ Constant=[nyoka_pmml.Constant(valueOf_=attribute.score.multiplier)])],
148
+ Constant=[nyoka_pmml.Constant(valueOf_=attribute.score.constant)])) if isinstance(
149
+ attribute.score, models.ComplexPartialScore) else None,
150
+ SimplePredicate=None if (attribute.predicate is None or not isinstance(
151
+ attribute.predicate, models.SimplePredicate)) else nyoka_pmml.SimplePredicate(
152
+ field=attribute.predicate.field,
153
+ operator=attribute.predicate.operator.name,
154
+ value=attribute.predicate.value),
155
+ CompoundPredicate=None if (attribute.predicate is None or not isinstance(
156
+ attribute.predicate, models.CompoundPredicate)) else nyoka_pmml.CompoundPredicate(
157
+ booleanOperator=attribute.predicate.booleanOperator.name,
158
+ SimplePredicate=[
159
+ nyoka_pmml.SimplePredicate(field=sp.field, operator=sp.operator.name, value=sp.value)
160
+ for sp in attribute.predicate.simplePredicates]),
161
+ True_=None if (attribute.predicate is None or not isinstance(
162
+ attribute.predicate, models.TruePredicate)) else nyoka_pmml.True_())
@@ -0,0 +1,3 @@
1
+ from .bins import LinearIntervalBin, IntervalBin, SetBin, Bin
2
+ from .partition import Partition
3
+ from .scorecard import Scorecard