howso-engine 60.3.1__tar.gz → 60.3.2__tar.gz
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.
- {howso_engine-60.3.1/howso_engine.egg-info → howso_engine-60.3.2}/PKG-INFO +1 -1
- howso_engine-60.3.2/howso/howso-engine/howso.caml +0 -0
- howso_engine-60.3.2/howso/howso-engine/migrations/migrations.caml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/howso-engine/version.json +3 -3
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/features.py +172 -164
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/tokenizing.py +5 -5
- {howso_engine-60.3.1 → howso_engine-60.3.2/howso_engine.egg-info}/PKG-INFO +1 -1
- howso_engine-60.3.2/version.json +5 -0
- howso_engine-60.3.1/howso/howso-engine/howso.caml +0 -0
- howso_engine-60.3.1/howso/howso-engine/migrations/migrations.caml +0 -0
- howso_engine-60.3.1/version.json +0 -5
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.coveragerc +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.flake8 +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.github/CODEOWNERS +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.github/templates/version_summary.md +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.github/workflows/build-pr.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.github/workflows/build-release.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.github/workflows/build.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.github/workflows/rebuild-requirements.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.github/workflows/version-update.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.gitignore +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.gitmodules +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/.pylintrc +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/CONTRIBUTING.md +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/LICENSE-3RD-PARTY.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/LICENSE.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/MANIFEST.in +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/Makefile +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/README.md +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/bin/build.sh +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/config/latest-mt-debug-howso.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/config/latest-mt-howso.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/config/latest-mt-noavx-traces-howso.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/config/latest-mt-traces-howso.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/config/latest-st-debug-howso.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/config/latest-st-howso.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/config/latest-st-traces-howso.yml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/config/powershell/Download-Tzdata.ps1 +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/config/powershell/Helper-Functions.ps1 +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/hatch.toml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/__main__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/__init__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/api.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/base.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/cache.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/client.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/configuration.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/exceptions.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/feature_flags.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/pandas/__init__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/pandas/client.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/protocols.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/schemas/__init__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/schemas/aggregate_reaction.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/schemas/base.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/schemas/group_reaction.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/schemas/project.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/schemas/reaction.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/schemas/session.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/schemas/trainee.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/schemas/version.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/client/typing.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/direct/__init__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/direct/_utilities.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/direct/client.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/direct/schemas/__init__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/direct/schemas/trainee.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/engine/__init__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/engine/client.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/engine/project.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/engine/session.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/engine/trainee.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/scikit/__init__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/scikit/scikit.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/__init__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/decorators.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/__init__.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/abstract_data.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/base.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/infer_feature_attributes.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/pandas.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/protocols.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/relational.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/serializers.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/suggestions.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/time_series.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/warnings.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/installation_verification.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/internals.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/json_wrapper.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/locale.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/monitors.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/posix.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/random.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/reaction.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/testing.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/utilities.py +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso_engine.egg-info/SOURCES.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso_engine.egg-info/dependency_links.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso_engine.egg-info/entry_points.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso_engine.egg-info/requires.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/howso_engine.egg-info/top_level.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/pyproject.toml +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/requirements-3.10-dev.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/requirements-3.10.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/requirements-3.11-dev.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/requirements-3.11.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/requirements-3.12-dev.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/requirements-3.12.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/requirements-3.13-dev.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/requirements-3.13.txt +0 -0
- {howso_engine-60.3.1 → howso_engine-60.3.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: howso-engine
|
|
3
|
-
Version: 60.3.
|
|
3
|
+
Version: 60.3.2
|
|
4
4
|
Summary: The Howso Engine™ is a natively and fully explainable ML engine, serving as an alternative to black box AI neural networks.
|
|
5
5
|
Author: Howso Incorporated
|
|
6
6
|
Author-email: support@howso.com
|
|
Binary file
|
|
Binary file
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "115.4.
|
|
2
|
+
"version": "115.4.2",
|
|
3
3
|
"dependencies": {
|
|
4
4
|
"amalgam": "80.0.2"
|
|
5
5
|
},
|
|
6
6
|
"display_title": "",
|
|
7
7
|
"build_date": "",
|
|
8
|
-
"sha": "
|
|
9
|
-
"url": "https://github.com/howsoai/howso-engine/releases/tag/115.4.
|
|
8
|
+
"sha": "fe48463b73c67b588acee0fcfa1c0aafb43a2de5",
|
|
9
|
+
"url": "https://github.com/howsoai/howso-engine/releases/tag/115.4.2"
|
|
10
10
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from collections.abc import Iterable, Mapping
|
|
3
|
+
from collections.abc import Iterable, Mapping, Sequence
|
|
4
4
|
import decimal
|
|
5
5
|
from enum import Enum
|
|
6
6
|
from functools import partial
|
|
7
7
|
import json
|
|
8
8
|
import locale
|
|
9
|
-
|
|
9
|
+
from typing import Any, cast
|
|
10
10
|
import warnings
|
|
11
11
|
from zoneinfo import ZoneInfo
|
|
12
12
|
|
|
@@ -17,11 +17,7 @@ from pandas.core.dtypes.common import (
|
|
|
17
17
|
is_timedelta64_dtype,
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
-
from .internals import
|
|
21
|
-
deserialize_to_dataframe,
|
|
22
|
-
IgnoreWarnings,
|
|
23
|
-
to_pandas_datetime_format
|
|
24
|
-
)
|
|
20
|
+
from .internals import deserialize_to_dataframe, IgnoreWarnings, to_pandas_datetime_format
|
|
25
21
|
from .tokenizing import (
|
|
26
22
|
HowsoTokenizer,
|
|
27
23
|
TokenizerProtocol,
|
|
@@ -36,7 +32,6 @@ from .utilities import (
|
|
|
36
32
|
tokenize_strings,
|
|
37
33
|
)
|
|
38
34
|
|
|
39
|
-
|
|
40
35
|
__all__ = [
|
|
41
36
|
"FeatureSerializer",
|
|
42
37
|
"FeatureType",
|
|
@@ -61,7 +56,7 @@ class FeatureType(Enum):
|
|
|
61
56
|
TIMEDELTA = "timedelta"
|
|
62
57
|
CONTAINER = "container"
|
|
63
58
|
|
|
64
|
-
def __str__(self):
|
|
59
|
+
def __str__(self) -> str:
|
|
65
60
|
"""Return a string representation."""
|
|
66
61
|
return str(self.value)
|
|
67
62
|
|
|
@@ -70,23 +65,23 @@ class FeatureSerializer:
|
|
|
70
65
|
"""Adapter for serialization and deserialization of feature data."""
|
|
71
66
|
|
|
72
67
|
@classmethod
|
|
73
|
-
def serialize( # noqa:
|
|
68
|
+
def serialize( # noqa: PLR0912
|
|
74
69
|
cls,
|
|
75
|
-
data:
|
|
76
|
-
columns:
|
|
77
|
-
features: Mapping,
|
|
70
|
+
data: pd.DataFrame | np.ndarray | Iterable[Any] | None,
|
|
71
|
+
columns: Sequence[str] | None,
|
|
72
|
+
features: Mapping[str, Any],
|
|
78
73
|
*,
|
|
79
|
-
tokenizer: TokenizerProtocol = None,
|
|
80
|
-
warn: bool = False
|
|
81
|
-
) -> list[list[
|
|
74
|
+
tokenizer: TokenizerProtocol | None = None,
|
|
75
|
+
warn: bool = False,
|
|
76
|
+
) -> list[list[Any]] | None:
|
|
82
77
|
"""
|
|
83
78
|
Serialize case data into list of lists.
|
|
84
79
|
|
|
85
80
|
Parameters
|
|
86
81
|
----------
|
|
87
|
-
data : pd.DataFrame or np.ndarray or Iterable
|
|
82
|
+
data : pd.DataFrame or np.ndarray or Iterable or None
|
|
88
83
|
The data to serialize, typically in a Pandas DataFrame, Numpy ndarray or Python Iterable such as a list.
|
|
89
|
-
columns :
|
|
84
|
+
columns : Sequence of str or None
|
|
90
85
|
The case column mapping. The order corresponds to the order of cases in output.
|
|
91
86
|
`columns` must be provided for non-DataFrame Iterables.
|
|
92
87
|
features : Mapping
|
|
@@ -115,15 +110,13 @@ class FeatureSerializer:
|
|
|
115
110
|
was received (should be either pd.DataFrame, np.ndarray or Python Iterable (non-str)).
|
|
116
111
|
"""
|
|
117
112
|
# Import locally to prevent a circular import
|
|
118
|
-
from howso.client.exceptions import HowsoError
|
|
113
|
+
from howso.client.exceptions import HowsoError # noqa: PLC0415
|
|
119
114
|
|
|
120
115
|
if data is None:
|
|
121
116
|
return None
|
|
122
117
|
if isinstance(data, np.ndarray):
|
|
123
118
|
if columns is None:
|
|
124
|
-
raise HowsoError(
|
|
125
|
-
"Columns must be provided with numpy arrays."
|
|
126
|
-
)
|
|
119
|
+
raise HowsoError("Columns must be provided with numpy arrays.")
|
|
127
120
|
data = pd.DataFrame.from_records(data, columns=columns)
|
|
128
121
|
|
|
129
122
|
if isinstance(data, pd.DataFrame):
|
|
@@ -133,8 +126,7 @@ class FeatureSerializer:
|
|
|
133
126
|
filtered_data = data[columns]
|
|
134
127
|
except KeyError as key_error:
|
|
135
128
|
raise HowsoError(
|
|
136
|
-
"The provided DataFrame is missing one or more of the "
|
|
137
|
-
f"expected named columns: {columns}."
|
|
129
|
+
f"The provided DataFrame is missing one or more of the expected named columns: {columns}."
|
|
138
130
|
) from key_error
|
|
139
131
|
else:
|
|
140
132
|
columns = data.columns.tolist()
|
|
@@ -145,8 +137,8 @@ class FeatureSerializer:
|
|
|
145
137
|
col_data = filtered_data[col]
|
|
146
138
|
if isinstance(col_data, pd.DataFrame):
|
|
147
139
|
raise ValueError(
|
|
148
|
-
"The provided DataFrame contains duplicate column "
|
|
149
|
-
|
|
140
|
+
"The provided DataFrame contains duplicate column names. All column names must be unique."
|
|
141
|
+
)
|
|
150
142
|
dtype = col_data.dtype
|
|
151
143
|
if is_datetime64_any_dtype(dtype):
|
|
152
144
|
# `to_pydatetime` emits a FutureWarning even when the issue
|
|
@@ -163,14 +155,12 @@ class FeatureSerializer:
|
|
|
163
155
|
|
|
164
156
|
elif isinstance(data, Iterable) and not isinstance(data, str):
|
|
165
157
|
if columns is None:
|
|
166
|
-
raise HowsoError(
|
|
167
|
-
"Columns must be provided with python Iterables."
|
|
168
|
-
)
|
|
158
|
+
raise HowsoError("Columns must be provided with python Iterables.")
|
|
169
159
|
result = list(data)
|
|
170
160
|
else:
|
|
171
161
|
raise ValueError(
|
|
172
|
-
"Received unexpected data type for case data. Cases "
|
|
173
|
-
|
|
162
|
+
"Received unexpected data type for case data. Cases should be either a DataFrame or a list."
|
|
163
|
+
)
|
|
174
164
|
|
|
175
165
|
# Convert 1d list (single case) to 2d list for serialization
|
|
176
166
|
# We check if the first item in the serialized list is a list
|
|
@@ -193,10 +183,10 @@ class FeatureSerializer:
|
|
|
193
183
|
@classmethod
|
|
194
184
|
def deserialize(
|
|
195
185
|
cls,
|
|
196
|
-
data: Iterable[Iterable[
|
|
197
|
-
columns:
|
|
198
|
-
features:
|
|
199
|
-
tokenizer:
|
|
186
|
+
data: Iterable[Iterable[Any] | Mapping[str, Any]],
|
|
187
|
+
columns: Sequence[str] | None = None,
|
|
188
|
+
features: Mapping[str, Any] | None = None,
|
|
189
|
+
tokenizer: TokenizerProtocol | None = None,
|
|
200
190
|
) -> pd.DataFrame:
|
|
201
191
|
"""
|
|
202
192
|
Deserialize case data into a DataFrame.
|
|
@@ -208,7 +198,7 @@ class FeatureSerializer:
|
|
|
208
198
|
----------
|
|
209
199
|
data : list of list or list of dict
|
|
210
200
|
The context data.
|
|
211
|
-
columns :
|
|
201
|
+
columns : Sequence of str, optional
|
|
212
202
|
The case column mapping. The order corresponds to the order of cases in output.
|
|
213
203
|
`columns` must be provided for non-DataFrame Iterables.
|
|
214
204
|
|
|
@@ -235,8 +225,12 @@ class FeatureSerializer:
|
|
|
235
225
|
return df
|
|
236
226
|
|
|
237
227
|
@classmethod
|
|
238
|
-
def format_dataframe(
|
|
239
|
-
|
|
228
|
+
def format_dataframe(
|
|
229
|
+
cls,
|
|
230
|
+
df: pd.DataFrame,
|
|
231
|
+
features: Mapping[str, Any],
|
|
232
|
+
tokenizer: TokenizerProtocol | None = None,
|
|
233
|
+
) -> pd.DataFrame:
|
|
240
234
|
"""
|
|
241
235
|
Format DataFrame columns to original type using feature attributes.
|
|
242
236
|
|
|
@@ -271,8 +265,12 @@ class FeatureSerializer:
|
|
|
271
265
|
return df
|
|
272
266
|
|
|
273
267
|
@classmethod
|
|
274
|
-
def format_column(
|
|
275
|
-
|
|
268
|
+
def format_column( # noqa: PLR0911
|
|
269
|
+
cls,
|
|
270
|
+
column: pd.Series,
|
|
271
|
+
feature: Mapping[str, Any] | None,
|
|
272
|
+
tokenizer: TokenizerProtocol | None = None,
|
|
273
|
+
) -> pd.Series:
|
|
276
274
|
"""
|
|
277
275
|
Format column based on feature typing information.
|
|
278
276
|
|
|
@@ -298,30 +296,28 @@ class FeatureSerializer:
|
|
|
298
296
|
|
|
299
297
|
if data_type == FeatureType.NUMERIC.value:
|
|
300
298
|
return cls.format_numeric_column(column, feature)
|
|
301
|
-
|
|
299
|
+
if data_type == FeatureType.INTEGER.value:
|
|
302
300
|
return cls.format_integer_column(column, feature)
|
|
303
|
-
|
|
301
|
+
if data_type == FeatureType.STRING.value:
|
|
304
302
|
return cls.format_string_column(column, feature)
|
|
305
|
-
|
|
303
|
+
if data_type == FeatureType.TOKENIZABLE_STRING.value:
|
|
306
304
|
return cls.format_tokenizable_string_column(column, feature, tokenizer=tokenizer)
|
|
307
|
-
|
|
305
|
+
if data_type == FeatureType.DATETIME.value:
|
|
308
306
|
return cls.format_datetime_column(column, feature)
|
|
309
|
-
|
|
307
|
+
if data_type == FeatureType.DATE.value:
|
|
310
308
|
return cls.format_date_column(column, feature)
|
|
311
|
-
|
|
309
|
+
if data_type == FeatureType.TIME.value:
|
|
312
310
|
return cls.format_time_column(column, feature)
|
|
313
|
-
|
|
311
|
+
if data_type == FeatureType.TIMEDELTA.value:
|
|
314
312
|
return cls.format_timedelta_column(column, feature)
|
|
315
|
-
|
|
313
|
+
if data_type == FeatureType.BOOLEAN.value:
|
|
316
314
|
return cls.format_boolean_column(column, feature)
|
|
317
|
-
|
|
315
|
+
if data_type == FeatureType.CONTAINER.value:
|
|
318
316
|
return cls.format_container_column(column, feature)
|
|
319
|
-
|
|
320
|
-
return cls.format_unknown_column(column, feature)
|
|
317
|
+
return cls.format_unknown_column(column, feature)
|
|
321
318
|
|
|
322
319
|
@classmethod
|
|
323
|
-
def format_timedelta_column(cls, column: pd.Series, feature: Mapping
|
|
324
|
-
) -> pd.Series:
|
|
320
|
+
def format_timedelta_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series:
|
|
325
321
|
"""
|
|
326
322
|
Format timedelta column.
|
|
327
323
|
|
|
@@ -339,27 +335,26 @@ class FeatureSerializer:
|
|
|
339
335
|
"""
|
|
340
336
|
typing_info = cls._get_typing_info(feature)
|
|
341
337
|
try:
|
|
342
|
-
unit = typing_info[
|
|
343
|
-
if unit not in [
|
|
344
|
-
raise ValueError(
|
|
338
|
+
unit = typing_info["unit"]
|
|
339
|
+
if unit not in ["days", "seconds", "nanoseconds"]:
|
|
340
|
+
raise ValueError("invalid unit type") # noqa: TRY301
|
|
345
341
|
except (TypeError, KeyError, ValueError):
|
|
346
342
|
warnings.warn(
|
|
347
|
-
f'Unknown timedelta unit for column "{column.name}", '
|
|
348
|
-
|
|
343
|
+
f'Unknown timedelta unit for column "{column.name}", column will not be translated to a timedelta64.'
|
|
344
|
+
)
|
|
349
345
|
return column
|
|
350
346
|
|
|
351
347
|
try:
|
|
352
348
|
return pd.to_timedelta(column, unit=unit)
|
|
353
|
-
except Exception: # noqa:
|
|
349
|
+
except Exception: # noqa: BLE001
|
|
354
350
|
warnings.warn(
|
|
355
351
|
f'Timedelta column "{column.name}" failed to be parsed as '
|
|
356
|
-
|
|
352
|
+
"timedelta64 values, column will retain current dtype."
|
|
357
353
|
)
|
|
358
354
|
return column
|
|
359
355
|
|
|
360
356
|
@classmethod
|
|
361
|
-
def format_datetime_column(cls, column: pd.Series, feature: Mapping
|
|
362
|
-
) -> pd.Series:
|
|
357
|
+
def format_datetime_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series:
|
|
363
358
|
"""
|
|
364
359
|
Format datetime column.
|
|
365
360
|
|
|
@@ -376,30 +371,30 @@ class FeatureSerializer:
|
|
|
376
371
|
The formatted column.
|
|
377
372
|
"""
|
|
378
373
|
typing_info = cls._get_typing_info(feature)
|
|
379
|
-
date_time_format = feature.get(
|
|
380
|
-
date_locale = feature.get(
|
|
374
|
+
date_time_format = feature.get("date_time_format") or None
|
|
375
|
+
date_locale = feature.get("locale") or None
|
|
381
376
|
format_includes_timezone = False
|
|
382
|
-
if (
|
|
383
|
-
date_time_format and
|
|
384
|
-
DATETIME_TIMEZONE_PATTERN.findall(date_time_format)
|
|
385
|
-
):
|
|
377
|
+
if date_time_format and DATETIME_TIMEZONE_PATTERN.findall(date_time_format):
|
|
386
378
|
format_includes_timezone = True
|
|
387
379
|
|
|
388
380
|
# Load timezone information if provided
|
|
389
|
-
tz = typing_info.get(
|
|
381
|
+
tz = typing_info.get("timezone")
|
|
390
382
|
if tz is not None:
|
|
391
383
|
try:
|
|
392
384
|
tz = ZoneInfo(tz)
|
|
393
385
|
except KeyError:
|
|
394
386
|
warnings.warn(
|
|
395
387
|
f'Unknown timezone "{tz}" for feature "{column.name}", '
|
|
396
|
-
|
|
397
|
-
|
|
388
|
+
"datetime column may not contain original timezone "
|
|
389
|
+
"information."
|
|
390
|
+
)
|
|
398
391
|
tz = None
|
|
399
392
|
|
|
400
|
-
def _to_datetime():
|
|
393
|
+
def _to_datetime() -> pd.Series:
|
|
401
394
|
# Format column to datetime
|
|
402
|
-
target_format =
|
|
395
|
+
target_format = None
|
|
396
|
+
if date_time_format is not None:
|
|
397
|
+
target_format = to_pandas_datetime_format(date_time_format)
|
|
403
398
|
if tz is not None:
|
|
404
399
|
if format_includes_timezone:
|
|
405
400
|
# When format string includes timezone we want to load
|
|
@@ -425,18 +420,20 @@ class FeatureSerializer:
|
|
|
425
420
|
warnings.warn(
|
|
426
421
|
f'Unable to parse column "{column.name}" as datetime64, the '
|
|
427
422
|
f'locale "{date_locale}" of the datetime does not appear to be '
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
423
|
+
"available on this system. Column will retain current dtype. "
|
|
424
|
+
"Note: This feature may not work properly until this locale "
|
|
425
|
+
"is installed."
|
|
426
|
+
)
|
|
427
|
+
except Exception: # noqa: BLE001
|
|
428
|
+
warnings.warn(
|
|
429
|
+
f'Unable to parse column "{column.name}" as '
|
|
430
|
+
f'datetime64 using format "{date_time_format}". '
|
|
431
|
+
"Column will retain current dtype."
|
|
432
|
+
)
|
|
435
433
|
return column
|
|
436
434
|
|
|
437
435
|
@classmethod
|
|
438
|
-
def format_date_column(cls, column: pd.Series, feature: Mapping
|
|
439
|
-
) -> pd.Series:
|
|
436
|
+
def format_date_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series:
|
|
440
437
|
"""
|
|
441
438
|
Format date only column.
|
|
442
439
|
|
|
@@ -452,9 +449,11 @@ class FeatureSerializer:
|
|
|
452
449
|
pandas.Series
|
|
453
450
|
The formatted column.
|
|
454
451
|
"""
|
|
455
|
-
date_time_format = feature.get(
|
|
456
|
-
date_locale = feature.get(
|
|
457
|
-
target_format =
|
|
452
|
+
date_time_format = feature.get("date_time_format") or None
|
|
453
|
+
date_locale = feature.get("locale") or None
|
|
454
|
+
target_format = None
|
|
455
|
+
if date_time_format is not None:
|
|
456
|
+
target_format = to_pandas_datetime_format(date_time_format)
|
|
458
457
|
try:
|
|
459
458
|
if date_locale:
|
|
460
459
|
with LocaleOverride(date_locale, category=locale.LC_TIME):
|
|
@@ -465,18 +464,20 @@ class FeatureSerializer:
|
|
|
465
464
|
warnings.warn(
|
|
466
465
|
f'Unable to parse column "{column.name}" as datetime64, the '
|
|
467
466
|
f'locale "{date_locale}" of the date does not appear to be '
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
467
|
+
"available on this system. Column will retain current dtype. "
|
|
468
|
+
"Note: This feature may not work properly until this locale "
|
|
469
|
+
"is installed."
|
|
470
|
+
)
|
|
471
|
+
except Exception: # noqa: BLE001
|
|
472
|
+
warnings.warn(
|
|
473
|
+
f'Unable to parse column "{column.name}" as '
|
|
474
|
+
f"datetime64 using format {date_time_format}. "
|
|
475
|
+
"Column will retain current dtype."
|
|
476
|
+
)
|
|
475
477
|
return column
|
|
476
478
|
|
|
477
479
|
@classmethod
|
|
478
|
-
def format_time_column(cls, column: pd.Series, feature: Mapping
|
|
479
|
-
) -> pd.Series:
|
|
480
|
+
def format_time_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series:
|
|
480
481
|
"""
|
|
481
482
|
Format time only column.
|
|
482
483
|
|
|
@@ -493,29 +494,28 @@ class FeatureSerializer:
|
|
|
493
494
|
The formatted column.
|
|
494
495
|
"""
|
|
495
496
|
typing_info = cls._get_typing_info(feature)
|
|
496
|
-
date_time_format = feature.get(
|
|
497
|
+
date_time_format = feature.get("date_time_format") or None
|
|
497
498
|
if date_time_format:
|
|
498
499
|
return cls.format_datetime_column(column, feature)
|
|
499
|
-
else:
|
|
500
|
-
# Time feature does not use a date_time_format, treat as seconds
|
|
501
|
-
tz = None
|
|
502
|
-
try:
|
|
503
|
-
tz_name = typing_info['timezone']
|
|
504
|
-
if tz_name is not None:
|
|
505
|
-
try:
|
|
506
|
-
tz = ZoneInfo(tz_name)
|
|
507
|
-
except KeyError:
|
|
508
|
-
warnings.warn(
|
|
509
|
-
f'Unknown timezone defined for column "{column.name}", '
|
|
510
|
-
'column will not be timezone aware.')
|
|
511
|
-
except (TypeError, KeyError):
|
|
512
|
-
pass
|
|
513
500
|
|
|
514
|
-
|
|
501
|
+
# Time feature does not use a date_time_format, treat as seconds
|
|
502
|
+
tz = None
|
|
503
|
+
try:
|
|
504
|
+
tz_name = typing_info["timezone"]
|
|
505
|
+
if tz_name is not None:
|
|
506
|
+
try:
|
|
507
|
+
tz = ZoneInfo(tz_name)
|
|
508
|
+
except KeyError:
|
|
509
|
+
warnings.warn(
|
|
510
|
+
f'Unknown timezone defined for column "{column.name}", column will not be timezone aware.'
|
|
511
|
+
)
|
|
512
|
+
except (TypeError, KeyError):
|
|
513
|
+
pass
|
|
514
|
+
|
|
515
|
+
return column.apply(partial(seconds_to_time, tzinfo=tz))
|
|
515
516
|
|
|
516
517
|
@classmethod
|
|
517
|
-
def format_boolean_column(cls, column: pd.Series, feature: Mapping
|
|
518
|
-
) -> pd.Series:
|
|
518
|
+
def format_boolean_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series: # noqa: ARG003
|
|
519
519
|
"""
|
|
520
520
|
Format boolean column.
|
|
521
521
|
|
|
@@ -532,20 +532,21 @@ class FeatureSerializer:
|
|
|
532
532
|
The formatted column.
|
|
533
533
|
"""
|
|
534
534
|
try:
|
|
535
|
-
|
|
535
|
+
|
|
536
|
+
def _apply_bool(value: Any) -> bool | None:
|
|
537
|
+
if pd.isna(value):
|
|
538
|
+
return value
|
|
536
539
|
if isinstance(value, str):
|
|
537
540
|
return value.lower() in ["true", "yes", "on", "(true)"]
|
|
538
541
|
return bool(value)
|
|
539
542
|
|
|
540
543
|
return column.apply(_apply_bool)
|
|
541
|
-
except Exception: # noqa:
|
|
542
|
-
warnings.warn(f'Unable to parse column "{column.name}" as '
|
|
543
|
-
f'boolean. Column will retain current dtype.')
|
|
544
|
+
except Exception: # noqa: BLE001
|
|
545
|
+
warnings.warn(f'Unable to parse column "{column.name}" as boolean. Column will retain current dtype.')
|
|
544
546
|
return column
|
|
545
547
|
|
|
546
548
|
@classmethod
|
|
547
|
-
def format_integer_column(cls, column: pd.Series, feature: Mapping
|
|
548
|
-
) -> pd.Series:
|
|
549
|
+
def format_integer_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series:
|
|
549
550
|
"""
|
|
550
551
|
Format integer column.
|
|
551
552
|
|
|
@@ -563,42 +564,45 @@ class FeatureSerializer:
|
|
|
563
564
|
"""
|
|
564
565
|
typing_info = cls._get_typing_info(feature)
|
|
565
566
|
|
|
566
|
-
has_nulls = column.
|
|
567
|
+
has_nulls = column.isna().any()
|
|
567
568
|
if has_nulls:
|
|
568
569
|
# Use pandas extension type for nullable integer
|
|
569
|
-
type_name =
|
|
570
|
+
type_name = "Int"
|
|
570
571
|
else:
|
|
571
|
-
type_name =
|
|
572
|
+
type_name = "int"
|
|
572
573
|
|
|
573
|
-
size = typing_info.get(
|
|
574
|
+
size = typing_info.get("size")
|
|
574
575
|
if size in [1, 2, 4, 8]:
|
|
575
|
-
type_name = f
|
|
576
|
-
unsigned = typing_info.get(
|
|
576
|
+
type_name = f"{type_name}{size * 8}"
|
|
577
|
+
unsigned = typing_info.get("unsigned")
|
|
577
578
|
if unsigned:
|
|
578
|
-
type_name = f
|
|
579
|
+
type_name = f"U{type_name}" if has_nulls else f"u{type_name}"
|
|
579
580
|
|
|
580
581
|
# unique or int-id features are output as 64bit ints, leave them
|
|
581
582
|
# as-is if original datatype is less than 64 bits
|
|
582
|
-
if
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
583
|
+
if (
|
|
584
|
+
size is not None
|
|
585
|
+
and size < 8
|
|
586
|
+
and (getattr(feature, "unique", False) or getattr(feature, "subtype", None) == "int-id")
|
|
587
|
+
):
|
|
588
|
+
warnings.warn(
|
|
589
|
+
f'Unable to restore column "{column.name}" as {type_name}. Column will retain current dtype.'
|
|
590
|
+
)
|
|
586
591
|
return column
|
|
587
592
|
|
|
588
593
|
try:
|
|
589
594
|
# We use floor and to_numeric here to handle cases where the value
|
|
590
595
|
# may be a string of float like values, so we get the column as a
|
|
591
596
|
# generic number first, remove the decimal places and then set the
|
|
592
|
-
# type to the expected format
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
+
# type to the expected format (np.floor will actually return a
|
|
598
|
+
# pandas series when given one, but the type hint only shows ndarray)
|
|
599
|
+
return cast(pd.Series, np.floor(pd.to_numeric(column)).astype(cast(np.dtype, type_name)))
|
|
600
|
+
except Exception: # noqa: BLE001
|
|
601
|
+
warnings.warn(f'Unable to parse column "{column.name}" as {type_name}. Column will retain current dtype.')
|
|
597
602
|
return column
|
|
598
603
|
|
|
599
604
|
@classmethod
|
|
600
|
-
def format_numeric_column(cls, column: pd.Series, feature: Mapping
|
|
601
|
-
) -> pd.Series:
|
|
605
|
+
def format_numeric_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series:
|
|
602
606
|
"""
|
|
603
607
|
Format numeric column.
|
|
604
608
|
|
|
@@ -615,41 +619,40 @@ class FeatureSerializer:
|
|
|
615
619
|
The formatted column.
|
|
616
620
|
"""
|
|
617
621
|
typing_info = cls._get_typing_info(feature)
|
|
618
|
-
number_format = typing_info.get(
|
|
619
|
-
type_name =
|
|
622
|
+
number_format = typing_info.get("format")
|
|
623
|
+
type_name = "float"
|
|
620
624
|
|
|
621
625
|
try:
|
|
622
|
-
if number_format ==
|
|
623
|
-
type_name =
|
|
626
|
+
if number_format == "decimal":
|
|
627
|
+
type_name = "Decimal"
|
|
624
628
|
# Note: We cast to string first here in attempt to prevent
|
|
625
629
|
# floating point errors.
|
|
626
|
-
return column.apply(lambda x: decimal.Decimal(
|
|
627
|
-
str(x)) if x is not None else None)
|
|
630
|
+
return column.apply(lambda x: decimal.Decimal(str(x)) if x is not None else None)
|
|
628
631
|
else:
|
|
629
|
-
type_name =
|
|
630
|
-
size = typing_info.get(
|
|
632
|
+
type_name = "float"
|
|
633
|
+
size = typing_info.get("size")
|
|
631
634
|
if size in [1, 2, 4, 8, 16]:
|
|
632
|
-
type_name = f
|
|
635
|
+
type_name = f"{type_name}{size * 8}"
|
|
633
636
|
|
|
634
637
|
# unique or int-id features are output as 64bit ints, leave them
|
|
635
638
|
# as-is if original datatype is less than 64 bits
|
|
636
|
-
if
|
|
637
|
-
|
|
639
|
+
if (
|
|
640
|
+
size is not None
|
|
641
|
+
and size < 8
|
|
642
|
+
and (getattr(feature, "unique", False) or getattr(feature, "subtype", None) == "int-id")
|
|
643
|
+
):
|
|
638
644
|
warnings.warn(
|
|
639
|
-
f'Unable to restore column "{column.name}" as '
|
|
640
|
-
f'{type_name}. Column will retain current dtype.'
|
|
645
|
+
f'Unable to restore column "{column.name}" as {type_name}. Column will retain current dtype.'
|
|
641
646
|
)
|
|
642
647
|
return column
|
|
643
648
|
|
|
644
|
-
return column.astype(type_name)
|
|
645
|
-
except Exception: # noqa:
|
|
646
|
-
warnings.warn(f'Unable to parse column "{column.name}" as '
|
|
647
|
-
f'{type_name}. Column will retain current dtype.')
|
|
649
|
+
return column.astype(cast(np.dtype, type_name))
|
|
650
|
+
except Exception: # noqa: BLE001
|
|
651
|
+
warnings.warn(f'Unable to parse column "{column.name}" as {type_name}. Column will retain current dtype.')
|
|
648
652
|
return column
|
|
649
653
|
|
|
650
654
|
@classmethod
|
|
651
|
-
def format_string_column(cls, column: pd.Series, feature: Mapping
|
|
652
|
-
) -> pd.Series:
|
|
655
|
+
def format_string_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series: # noqa: ARG003
|
|
653
656
|
"""
|
|
654
657
|
Format string column.
|
|
655
658
|
|
|
@@ -669,8 +672,12 @@ class FeatureSerializer:
|
|
|
669
672
|
return column
|
|
670
673
|
|
|
671
674
|
@classmethod
|
|
672
|
-
def format_tokenizable_string_column(
|
|
673
|
-
|
|
675
|
+
def format_tokenizable_string_column(
|
|
676
|
+
cls,
|
|
677
|
+
column: pd.Series,
|
|
678
|
+
feature: Mapping[str, Any], # noqa: ARG003
|
|
679
|
+
tokenizer: TokenizerProtocol | None = None,
|
|
680
|
+
) -> pd.Series:
|
|
674
681
|
"""
|
|
675
682
|
Format tokenizable string column.
|
|
676
683
|
|
|
@@ -694,8 +701,7 @@ class FeatureSerializer:
|
|
|
694
701
|
return pd.Series(tokenizer.detokenize(json.loads(case)) for case in column)
|
|
695
702
|
|
|
696
703
|
@classmethod
|
|
697
|
-
def format_unknown_column(cls, column: pd.Series, feature: Mapping
|
|
698
|
-
) -> pd.Series:
|
|
704
|
+
def format_unknown_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series: # noqa: ARG003
|
|
699
705
|
"""
|
|
700
706
|
Format unknown typed column.
|
|
701
707
|
|
|
@@ -715,7 +721,7 @@ class FeatureSerializer:
|
|
|
715
721
|
return column
|
|
716
722
|
|
|
717
723
|
@classmethod
|
|
718
|
-
def format_container_column(cls, column: pd.Series, feature: Mapping) -> pd.Series:
|
|
724
|
+
def format_container_column(cls, column: pd.Series, feature: Mapping[str, Any]) -> pd.Series:
|
|
719
725
|
"""
|
|
720
726
|
Format a container column (a Python Mapping/Sequence).
|
|
721
727
|
|
|
@@ -734,7 +740,7 @@ class FeatureSerializer:
|
|
|
734
740
|
return destringify_json(column, feature)
|
|
735
741
|
|
|
736
742
|
@staticmethod
|
|
737
|
-
def _get_typing_info(feature:
|
|
743
|
+
def _get_typing_info(feature: Mapping[str, Any] | None) -> dict:
|
|
738
744
|
"""
|
|
739
745
|
Get typing info from feature attributes.
|
|
740
746
|
|
|
@@ -748,11 +754,13 @@ class FeatureSerializer:
|
|
|
748
754
|
dict
|
|
749
755
|
The typing info for the feature. Or empty dict if none found.
|
|
750
756
|
"""
|
|
757
|
+
if feature is None:
|
|
758
|
+
return {}
|
|
751
759
|
try:
|
|
752
|
-
typing_info = feature[
|
|
760
|
+
typing_info = feature["original_type"]
|
|
753
761
|
except (TypeError, KeyError):
|
|
754
|
-
return
|
|
755
|
-
return typing_info or
|
|
762
|
+
return {}
|
|
763
|
+
return typing_info or {}
|
|
756
764
|
|
|
757
765
|
|
|
758
766
|
serialize_cases = FeatureSerializer.serialize
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Protocol, runtime_checkable
|
|
1
|
+
from typing import Any, Protocol, runtime_checkable
|
|
2
2
|
|
|
3
3
|
from sacremoses import MosesDetokenizer, MosesTokenizer
|
|
4
4
|
|
|
@@ -9,11 +9,11 @@ class TokenizerProtocol(Protocol):
|
|
|
9
9
|
|
|
10
10
|
def tokenize(self, text: str, **kwargs) -> list[str]:
|
|
11
11
|
"""Tokenize a string."""
|
|
12
|
-
|
|
12
|
+
...
|
|
13
13
|
|
|
14
14
|
def detokenize(self, tokens: list[str], **kwargs) -> str:
|
|
15
15
|
"""Detokenize a list of tokens into a string."""
|
|
16
|
-
|
|
16
|
+
...
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class HowsoTokenizer:
|
|
@@ -25,7 +25,7 @@ class HowsoTokenizer:
|
|
|
25
25
|
self._mt = MosesTokenizer(lang=self.lang)
|
|
26
26
|
self._md = MosesDetokenizer(lang=self.lang)
|
|
27
27
|
|
|
28
|
-
def tokenize(self, text: str) -> list[str]:
|
|
28
|
+
def tokenize(self, text: str, **kwargs: Any) -> list[str]:
|
|
29
29
|
"""
|
|
30
30
|
Tokenizes a string into a list of strings.
|
|
31
31
|
|
|
@@ -41,7 +41,7 @@ class HowsoTokenizer:
|
|
|
41
41
|
"""
|
|
42
42
|
return self._mt.tokenize(text)
|
|
43
43
|
|
|
44
|
-
def detokenize(self, tokens: list[str]) -> str:
|
|
44
|
+
def detokenize(self, tokens: list[str], **kwargs: Any) -> str:
|
|
45
45
|
"""
|
|
46
46
|
Detokenizes a list of strings into a string.
|
|
47
47
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: howso-engine
|
|
3
|
-
Version: 60.3.
|
|
3
|
+
Version: 60.3.2
|
|
4
4
|
Summary: The Howso Engine™ is a natively and fully explainable ML engine, serving as an alternative to black box AI neural networks.
|
|
5
5
|
Author: Howso Incorporated
|
|
6
6
|
Author-email: support@howso.com
|
|
Binary file
|
|
Binary file
|
howso_engine-60.3.1/version.json
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/abstract_data.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/relational.py
RENAMED
|
File without changes
|
{howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/serializers.py
RENAMED
|
File without changes
|
{howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/suggestions.py
RENAMED
|
File without changes
|
{howso_engine-60.3.1 → howso_engine-60.3.2}/howso/utilities/feature_attributes/time_series.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|