upgini 1.1.262a3250.post3__py3-none-any.whl → 1.1.274a4__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.
- upgini/autofe/all_operands.py +12 -2
- upgini/autofe/date.py +68 -8
- upgini/autofe/feature.py +1 -1
- upgini/data_source/data_source_publisher.py +24 -5
- upgini/dataset.py +21 -58
- upgini/features_enricher.py +114 -40
- upgini/fingerprint.js +8 -0
- upgini/metrics.py +58 -7
- upgini/normalizer/phone_normalizer.py +2 -2
- upgini/resource_bundle/strings.properties +8 -3
- upgini/search_task.py +1 -1
- upgini/utils/datetime_utils.py +53 -2
- upgini/utils/deduplicate_utils.py +61 -18
- upgini/utils/sklearn_ext.py +1 -2
- upgini/utils/target_utils.py +125 -2
- {upgini-1.1.262a3250.post3.dist-info → upgini-1.1.274a4.dist-info}/METADATA +2 -2
- {upgini-1.1.262a3250.post3.dist-info → upgini-1.1.274a4.dist-info}/RECORD +20 -19
- {upgini-1.1.262a3250.post3.dist-info → upgini-1.1.274a4.dist-info}/LICENSE +0 -0
- {upgini-1.1.262a3250.post3.dist-info → upgini-1.1.274a4.dist-info}/WHEEL +0 -0
- {upgini-1.1.262a3250.post3.dist-info → upgini-1.1.274a4.dist-info}/top_level.txt +0 -0
upgini/features_enricher.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
+
import datetime
|
|
2
3
|
import gc
|
|
3
4
|
import hashlib
|
|
4
5
|
import itertools
|
|
@@ -70,6 +71,7 @@ from upgini.utils.datetime_utils import (
|
|
|
70
71
|
DateTimeSearchKeyConverter,
|
|
71
72
|
is_blocked_time_series,
|
|
72
73
|
is_time_series,
|
|
74
|
+
validate_dates_distribution,
|
|
73
75
|
)
|
|
74
76
|
from upgini.utils.deduplicate_utils import (
|
|
75
77
|
clean_full_duplicates,
|
|
@@ -93,7 +95,7 @@ try:
|
|
|
93
95
|
except Exception:
|
|
94
96
|
from upgini.utils.fallback_progress_bar import CustomFallbackProgressBar as ProgressBar
|
|
95
97
|
|
|
96
|
-
from upgini.utils.target_utils import define_task
|
|
98
|
+
from upgini.utils.target_utils import calculate_psi, define_task
|
|
97
99
|
from upgini.utils.warning_counter import WarningCounter
|
|
98
100
|
from upgini.version_validator import validate_version
|
|
99
101
|
|
|
@@ -145,6 +147,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
145
147
|
"""
|
|
146
148
|
|
|
147
149
|
TARGET_NAME = "target"
|
|
150
|
+
CURRENT_DATE = "current_date"
|
|
148
151
|
RANDOM_STATE = 42
|
|
149
152
|
CALCULATE_METRICS_THRESHOLD = 50_000_000
|
|
150
153
|
CALCULATE_METRICS_MIN_THRESHOLD = 500
|
|
@@ -206,6 +209,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
206
209
|
client_ip: Optional[str] = None,
|
|
207
210
|
client_visitorid: Optional[str] = None,
|
|
208
211
|
custom_bundle_config: Optional[str] = None,
|
|
212
|
+
add_date_if_missing: bool = True,
|
|
209
213
|
**kwargs,
|
|
210
214
|
):
|
|
211
215
|
self.bundle = get_custom_bundle(custom_bundle_config)
|
|
@@ -220,7 +224,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
220
224
|
if logs_enabled:
|
|
221
225
|
self.logger = LoggerFactory().get_logger(endpoint, self._api_key, client_ip, client_visitorid)
|
|
222
226
|
else:
|
|
223
|
-
self.logger = logging.getLogger()
|
|
227
|
+
self.logger = logging.getLogger("muted_logger")
|
|
224
228
|
self.logger.setLevel("FATAL")
|
|
225
229
|
|
|
226
230
|
if len(kwargs) > 0:
|
|
@@ -316,6 +320,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
316
320
|
self.raise_validation_error = raise_validation_error
|
|
317
321
|
self.exclude_columns = exclude_columns
|
|
318
322
|
self.baseline_score_column = baseline_score_column
|
|
323
|
+
self.add_date_if_missing = add_date_if_missing
|
|
319
324
|
|
|
320
325
|
def _get_api_key(self):
|
|
321
326
|
return self._api_key
|
|
@@ -423,7 +428,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
423
428
|
self.X = X
|
|
424
429
|
self.y = y
|
|
425
430
|
self.eval_set = self._check_eval_set(eval_set, X, self.bundle)
|
|
426
|
-
self.dump_input(trace_id, X, y, eval_set)
|
|
431
|
+
self.dump_input(trace_id, X, y, self.eval_set)
|
|
427
432
|
self.__inner_fit(
|
|
428
433
|
trace_id,
|
|
429
434
|
X,
|
|
@@ -562,7 +567,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
562
567
|
self.X = X
|
|
563
568
|
self.y = y
|
|
564
569
|
self.eval_set = self._check_eval_set(eval_set, X, self.bundle)
|
|
565
|
-
self.dump_input(trace_id, X, y, eval_set)
|
|
570
|
+
self.dump_input(trace_id, X, y, self.eval_set)
|
|
566
571
|
|
|
567
572
|
if _num_samples(drop_duplicates(X)) > Dataset.MAX_ROWS:
|
|
568
573
|
raise ValidationError(self.bundle.get("dataset_too_many_rows_registered").format(Dataset.MAX_ROWS))
|
|
@@ -822,12 +827,16 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
822
827
|
print(msg)
|
|
823
828
|
|
|
824
829
|
self.__validate_search_keys(self.search_keys, self.search_id)
|
|
830
|
+
effective_X = X if X is not None else self.X
|
|
831
|
+
effective_y = y if y is not None else self.y
|
|
832
|
+
effective_eval_set = eval_set if eval_set is not None else self.eval_set
|
|
833
|
+
effective_eval_set = self._check_eval_set(effective_eval_set, effective_X, self.bundle)
|
|
825
834
|
|
|
826
835
|
try:
|
|
827
836
|
self.__log_debug_information(
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
837
|
+
effective_X,
|
|
838
|
+
effective_y,
|
|
839
|
+
effective_eval_set,
|
|
831
840
|
exclude_features_sources=exclude_features_sources,
|
|
832
841
|
cv=cv if cv is not None else self.cv,
|
|
833
842
|
importance_threshold=importance_threshold,
|
|
@@ -841,17 +850,14 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
841
850
|
self._search_task is None
|
|
842
851
|
or self._search_task.provider_metadata_v2 is None
|
|
843
852
|
or len(self._search_task.provider_metadata_v2) == 0
|
|
844
|
-
or
|
|
845
|
-
or
|
|
853
|
+
or effective_X is None
|
|
854
|
+
or effective_y is None
|
|
846
855
|
):
|
|
847
856
|
raise ValidationError(self.bundle.get("metrics_unfitted_enricher"))
|
|
848
857
|
|
|
849
858
|
if X is not None and y is None:
|
|
850
859
|
raise ValidationError("X passed without y")
|
|
851
860
|
|
|
852
|
-
effective_X = X if X is not None else self.X
|
|
853
|
-
effective_eval_set = eval_set if eval_set is not None else self.eval_set
|
|
854
|
-
|
|
855
861
|
validate_scoring_argument(scoring)
|
|
856
862
|
|
|
857
863
|
self._validate_baseline_score(effective_X, effective_eval_set)
|
|
@@ -871,8 +877,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
871
877
|
):
|
|
872
878
|
cat_features = estimator.get_param("cat_features")
|
|
873
879
|
if len(cat_features) > 0 and isinstance(cat_features[0], int):
|
|
874
|
-
|
|
875
|
-
cat_features = [effectiveX.columns[i] for i in cat_features]
|
|
880
|
+
cat_features = [effective_X.columns[i] for i in cat_features]
|
|
876
881
|
for cat_feature in cat_features:
|
|
877
882
|
if cat_feature in self.search_keys:
|
|
878
883
|
if self.search_keys[cat_feature] in [SearchKey.COUNTRY, SearchKey.POSTAL_CODE]:
|
|
@@ -882,9 +887,9 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
882
887
|
|
|
883
888
|
prepared_data = self._prepare_data_for_metrics(
|
|
884
889
|
trace_id=trace_id,
|
|
885
|
-
X=
|
|
886
|
-
y=
|
|
887
|
-
eval_set=
|
|
890
|
+
X=effective_X,
|
|
891
|
+
y=effective_y,
|
|
892
|
+
eval_set=effective_eval_set,
|
|
888
893
|
exclude_features_sources=exclude_features_sources,
|
|
889
894
|
importance_threshold=importance_threshold,
|
|
890
895
|
max_features=max_features,
|
|
@@ -994,8 +999,6 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
994
999
|
enriched_metric = None
|
|
995
1000
|
uplift = None
|
|
996
1001
|
|
|
997
|
-
effective_X = X if X is not None else self.X
|
|
998
|
-
effective_y = y if y is not None else self.y
|
|
999
1002
|
train_metrics = {
|
|
1000
1003
|
self.bundle.get("quality_metrics_segment_header"): self.bundle.get(
|
|
1001
1004
|
"quality_metrics_train_segment"
|
|
@@ -1256,6 +1259,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
1256
1259
|
).get_cv_and_groups(X)
|
|
1257
1260
|
else:
|
|
1258
1261
|
from sklearn import __version__ as sklearn_version
|
|
1262
|
+
|
|
1259
1263
|
try:
|
|
1260
1264
|
from sklearn.model_selection._split import GroupsConsumerMixin
|
|
1261
1265
|
|
|
@@ -1684,6 +1688,9 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
1684
1688
|
df = validated_X.copy()
|
|
1685
1689
|
|
|
1686
1690
|
df[TARGET] = validated_y
|
|
1691
|
+
|
|
1692
|
+
df = clean_full_duplicates(df, logger=self.logger, silent=True, bundle=self.bundle)
|
|
1693
|
+
|
|
1687
1694
|
num_samples = _num_samples(df)
|
|
1688
1695
|
if num_samples > Dataset.FIT_SAMPLE_THRESHOLD:
|
|
1689
1696
|
self.logger.info(f"Downsampling from {num_samples} to {Dataset.FIT_SAMPLE_ROWS}")
|
|
@@ -1801,10 +1808,11 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
1801
1808
|
else:
|
|
1802
1809
|
features_section = ""
|
|
1803
1810
|
|
|
1804
|
-
|
|
1811
|
+
search_id = self._search_task.search_task_id
|
|
1812
|
+
api_example = f"""curl 'https://search.upgini.com/online/api/http_inference_trigger?search_id={search_id}' \\
|
|
1805
1813
|
-H 'Authorization: {self.api_key}' \\
|
|
1806
1814
|
-H 'Content-Type: application/json' \\
|
|
1807
|
-
-d '{{"
|
|
1815
|
+
-d '{{"search_keys": {keys}{features_section}}}'"""
|
|
1808
1816
|
return api_example
|
|
1809
1817
|
|
|
1810
1818
|
def _get_copy_of_runtime_parameters(self) -> RuntimeParameters:
|
|
@@ -1899,6 +1907,8 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
1899
1907
|
generated_features.extend(converter.generated_features)
|
|
1900
1908
|
else:
|
|
1901
1909
|
self.logger.info("Input dataset hasn't date column")
|
|
1910
|
+
if self.add_date_if_missing:
|
|
1911
|
+
df = self._add_current_date_as_key(df, search_keys, self.logger, self.bundle)
|
|
1902
1912
|
email_column = self._get_email_column(search_keys)
|
|
1903
1913
|
hem_column = self._get_hem_column(search_keys)
|
|
1904
1914
|
email_converted_to_hem = False
|
|
@@ -1918,6 +1928,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
1918
1928
|
|
|
1919
1929
|
meaning_types = {col: key.value for col, key in search_keys.items()}
|
|
1920
1930
|
non_keys_columns = [column for column in df.columns if column not in search_keys.keys()]
|
|
1931
|
+
|
|
1921
1932
|
if email_converted_to_hem:
|
|
1922
1933
|
non_keys_columns.append(email_column)
|
|
1923
1934
|
|
|
@@ -1939,6 +1950,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
1939
1950
|
if add_fit_system_record_id:
|
|
1940
1951
|
df = self.__add_fit_system_record_id(df, dict(), search_keys)
|
|
1941
1952
|
df = df.rename(columns={SYSTEM_RECORD_ID: SORT_ID})
|
|
1953
|
+
non_keys_columns.append(SORT_ID)
|
|
1942
1954
|
|
|
1943
1955
|
columns_for_system_record_id = sorted(list(search_keys.keys()) + (original_features_for_transform or []))
|
|
1944
1956
|
|
|
@@ -2215,14 +2227,13 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
2215
2227
|
self.fit_search_keys = self.search_keys.copy()
|
|
2216
2228
|
self.fit_search_keys = self.__prepare_search_keys(validated_X, self.fit_search_keys, is_demo_dataset)
|
|
2217
2229
|
|
|
2218
|
-
|
|
2230
|
+
validate_dates_distribution(validated_X, self.fit_search_keys, self.logger, self.bundle, self.warning_counter)
|
|
2231
|
+
|
|
2232
|
+
maybe_date_column = self._get_date_column(self.fit_search_keys)
|
|
2233
|
+
has_date = maybe_date_column is not None
|
|
2219
2234
|
model_task_type = self.model_task_type or define_task(validated_y, has_date, self.logger)
|
|
2220
2235
|
self._validate_binary_observations(validated_y, model_task_type)
|
|
2221
2236
|
|
|
2222
|
-
df = self.__handle_index_search_keys(df, self.fit_search_keys)
|
|
2223
|
-
|
|
2224
|
-
df = self.__correct_target(df)
|
|
2225
|
-
|
|
2226
2237
|
self.runtime_parameters = get_runtime_params_custom_loss(
|
|
2227
2238
|
self.loss, model_task_type, self.runtime_parameters, self.logger
|
|
2228
2239
|
)
|
|
@@ -2234,6 +2245,13 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
2234
2245
|
eval_df[EVAL_SET_INDEX] = idx + 1
|
|
2235
2246
|
df = pd.concat([df, eval_df])
|
|
2236
2247
|
|
|
2248
|
+
df = self.__correct_target(df)
|
|
2249
|
+
|
|
2250
|
+
df = self.__handle_index_search_keys(df, self.fit_search_keys)
|
|
2251
|
+
|
|
2252
|
+
if is_numeric_dtype(df[self.TARGET_NAME]) and has_date:
|
|
2253
|
+
self._validate_PSI(df.sort_values(by=maybe_date_column))
|
|
2254
|
+
|
|
2237
2255
|
if DEFAULT_INDEX in df.columns:
|
|
2238
2256
|
msg = self.bundle.get("unsupported_index_column")
|
|
2239
2257
|
self.logger.info(msg)
|
|
@@ -2260,6 +2278,8 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
2260
2278
|
self.fit_generated_features.extend(converter.generated_features)
|
|
2261
2279
|
else:
|
|
2262
2280
|
self.logger.info("Input dataset hasn't date column")
|
|
2281
|
+
if self.add_date_if_missing:
|
|
2282
|
+
df = self._add_current_date_as_key(df, self.fit_search_keys, self.logger, self.bundle)
|
|
2263
2283
|
email_column = self._get_email_column(self.fit_search_keys)
|
|
2264
2284
|
hem_column = self._get_hem_column(self.fit_search_keys)
|
|
2265
2285
|
email_converted_to_hem = False
|
|
@@ -2808,6 +2828,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
2808
2828
|
|
|
2809
2829
|
maybe_date_col = self._get_date_column(self.search_keys)
|
|
2810
2830
|
if X is not None and maybe_date_col is not None and maybe_date_col in X.columns:
|
|
2831
|
+
# TODO cast date column to single dtype
|
|
2811
2832
|
min_date = X[maybe_date_col].min()
|
|
2812
2833
|
max_date = X[maybe_date_col].max()
|
|
2813
2834
|
self.logger.info(f"Dates interval is ({min_date}, {max_date})")
|
|
@@ -2839,6 +2860,25 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
2839
2860
|
if t in [SearchKey.DATE, SearchKey.DATETIME]:
|
|
2840
2861
|
return col
|
|
2841
2862
|
|
|
2863
|
+
@staticmethod
|
|
2864
|
+
def _add_current_date_as_key(
|
|
2865
|
+
df: pd.DataFrame, search_keys: Dict[str, SearchKey], logger: logging.Logger, bundle: ResourceBundle
|
|
2866
|
+
) -> pd.DataFrame:
|
|
2867
|
+
if (
|
|
2868
|
+
set(search_keys.values()) == {SearchKey.PHONE}
|
|
2869
|
+
or set(search_keys.values()) == {SearchKey.EMAIL}
|
|
2870
|
+
or set(search_keys.values()) == {SearchKey.HEM}
|
|
2871
|
+
or set(search_keys.values()) == {SearchKey.COUNTRY, SearchKey.POSTAL_CODE}
|
|
2872
|
+
):
|
|
2873
|
+
msg = bundle.get("current_date_added")
|
|
2874
|
+
print(msg)
|
|
2875
|
+
logger.warning(msg)
|
|
2876
|
+
df[FeaturesEnricher.CURRENT_DATE] = datetime.date.today()
|
|
2877
|
+
search_keys[FeaturesEnricher.CURRENT_DATE] = SearchKey.DATE
|
|
2878
|
+
converter = DateTimeSearchKeyConverter(FeaturesEnricher.CURRENT_DATE, None, logger, bundle)
|
|
2879
|
+
df = converter.convert(df)
|
|
2880
|
+
return df
|
|
2881
|
+
|
|
2842
2882
|
@staticmethod
|
|
2843
2883
|
def _get_group_columns(df: pd.DataFrame, search_keys: Dict[str, SearchKey]) -> List[str]:
|
|
2844
2884
|
return [
|
|
@@ -2877,26 +2917,33 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
2877
2917
|
|
|
2878
2918
|
# order by date and idempotent order by other keys
|
|
2879
2919
|
if self.cv not in [CVType.time_series, CVType.blocked_time_series]:
|
|
2920
|
+
sort_exclude_columns = [original_order_name, ORIGINAL_INDEX, EVAL_SET_INDEX, TARGET, "__target"]
|
|
2880
2921
|
if DateTimeSearchKeyConverter.DATETIME_COL in df.columns:
|
|
2881
2922
|
date_column = DateTimeSearchKeyConverter.DATETIME_COL
|
|
2923
|
+
sort_exclude_columns.append(self._get_date_column(search_keys))
|
|
2882
2924
|
else:
|
|
2883
2925
|
date_column = self._get_date_column(search_keys)
|
|
2884
2926
|
sort_columns = [date_column] if date_column is not None else []
|
|
2885
2927
|
|
|
2886
|
-
|
|
2928
|
+
other_columns = sorted(
|
|
2887
2929
|
[
|
|
2888
|
-
|
|
2889
|
-
for
|
|
2890
|
-
if
|
|
2891
|
-
and sk in df.columns
|
|
2892
|
-
and df[sk].nunique() > 1 # don't use constant keys for hash
|
|
2930
|
+
c
|
|
2931
|
+
for c in df.columns
|
|
2932
|
+
if c not in sort_columns and c not in sort_exclude_columns and df[c].nunique() > 1
|
|
2893
2933
|
]
|
|
2934
|
+
# [
|
|
2935
|
+
# sk
|
|
2936
|
+
# for sk, key_type in search_keys.items()
|
|
2937
|
+
# if key_type not in [SearchKey.DATE, SearchKey.DATETIME]
|
|
2938
|
+
# and sk in df.columns
|
|
2939
|
+
# and df[sk].nunique() > 1 # don't use constant keys for hash
|
|
2940
|
+
# ]
|
|
2894
2941
|
)
|
|
2895
2942
|
|
|
2896
2943
|
search_keys_hash = "search_keys_hash"
|
|
2897
|
-
if len(
|
|
2944
|
+
if len(other_columns) > 0:
|
|
2898
2945
|
sort_columns.append(search_keys_hash)
|
|
2899
|
-
df[search_keys_hash] = pd.util.hash_pandas_object(df[
|
|
2946
|
+
df[search_keys_hash] = pd.util.hash_pandas_object(df[other_columns], index=False)
|
|
2900
2947
|
|
|
2901
2948
|
df = df.sort_values(by=sort_columns)
|
|
2902
2949
|
|
|
@@ -3185,22 +3232,21 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
3185
3232
|
return None
|
|
3186
3233
|
features_meta = self._search_task.get_all_features_metadata_v2()
|
|
3187
3234
|
|
|
3188
|
-
def
|
|
3235
|
+
def get_feature_by_name(name: str):
|
|
3189
3236
|
for m in features_meta:
|
|
3190
|
-
if m.name
|
|
3237
|
+
if m.name == name:
|
|
3191
3238
|
return m
|
|
3192
3239
|
|
|
3193
3240
|
descriptions = []
|
|
3194
3241
|
for m in autofe_meta:
|
|
3195
3242
|
autofe_feature = Feature.from_formula(m.formula)
|
|
3243
|
+
autofe_feature.set_display_index(m.display_index)
|
|
3196
3244
|
if autofe_feature.op.is_vector:
|
|
3197
3245
|
continue
|
|
3198
3246
|
|
|
3199
3247
|
description = dict()
|
|
3200
3248
|
|
|
3201
|
-
feature_meta =
|
|
3202
|
-
m.display_index, autofe_feature.op.alias or autofe_feature.op.name
|
|
3203
|
-
)
|
|
3249
|
+
feature_meta = get_feature_by_name(autofe_feature.get_display_name(shorten=True))
|
|
3204
3250
|
if feature_meta is None:
|
|
3205
3251
|
self.logger.warning(f"Feature meta for display index {m.display_index} not found")
|
|
3206
3252
|
continue
|
|
@@ -3547,6 +3593,34 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
3547
3593
|
self.logger.warning(msg)
|
|
3548
3594
|
print(msg)
|
|
3549
3595
|
|
|
3596
|
+
def _validate_PSI(self, df: pd.DataFrame):
|
|
3597
|
+
if EVAL_SET_INDEX in df.columns:
|
|
3598
|
+
train = df.query(f"{EVAL_SET_INDEX} == 0")
|
|
3599
|
+
eval1 = df.query(f"{EVAL_SET_INDEX} == 1")
|
|
3600
|
+
else:
|
|
3601
|
+
train = df
|
|
3602
|
+
eval1 = None
|
|
3603
|
+
|
|
3604
|
+
# 1. Check train PSI
|
|
3605
|
+
half_train = round(len(train) / 2)
|
|
3606
|
+
part1 = train[:half_train]
|
|
3607
|
+
part2 = train[half_train:]
|
|
3608
|
+
train_psi = calculate_psi(part1[self.TARGET_NAME], part2[self.TARGET_NAME])
|
|
3609
|
+
if train_psi > 0.2:
|
|
3610
|
+
self.warning_counter.increment()
|
|
3611
|
+
msg = self.bundle.get("train_unstable_target").format(train_psi)
|
|
3612
|
+
print(msg)
|
|
3613
|
+
self.logger.warning(msg)
|
|
3614
|
+
|
|
3615
|
+
# 2. Check train-test PSI
|
|
3616
|
+
if eval1 is not None:
|
|
3617
|
+
train_test_psi = calculate_psi(train[self.TARGET_NAME], eval1[self.TARGET_NAME])
|
|
3618
|
+
if train_test_psi > 0.2:
|
|
3619
|
+
self.warning_counter.increment()
|
|
3620
|
+
msg = self.bundle.get("eval_unstable_target").format(train_test_psi)
|
|
3621
|
+
print(msg)
|
|
3622
|
+
self.logger.warning(msg)
|
|
3623
|
+
|
|
3550
3624
|
def _dump_python_libs(self):
|
|
3551
3625
|
try:
|
|
3552
3626
|
from pip._internal.operations.freeze import freeze
|
|
@@ -3613,7 +3687,7 @@ class FeaturesEnricher(TransformerMixin):
|
|
|
3613
3687
|
if y is not None:
|
|
3614
3688
|
with open(f"{tmp_dir}/y.pickle", "wb") as y_file:
|
|
3615
3689
|
pickle.dump(sample(y, xy_sample_index), y_file)
|
|
3616
|
-
if eval_set
|
|
3690
|
+
if eval_set:
|
|
3617
3691
|
eval_xy_sample_index = rnd.randint(0, _num_samples(eval_set[0][0]), size=1000)
|
|
3618
3692
|
with open(f"{tmp_dir}/eval_x.pickle", "wb") as eval_x_file:
|
|
3619
3693
|
pickle.dump(sample(eval_set[0][0], eval_xy_sample_index), eval_x_file)
|
upgini/fingerprint.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FingerprintJS v3.4.2 - Copyright (c) FingerprintJS, Inc, 2023 (https://fingerprint.com)
|
|
3
|
+
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
|
|
4
|
+
*
|
|
5
|
+
* This software contains code from open-source projects:
|
|
6
|
+
* MurmurHash3 by Karan Lyons (https://github.com/karanlyons/murmurHash3.js)
|
|
7
|
+
*/
|
|
8
|
+
var e=function(){return e=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},e.apply(this,arguments)};function n(e,n,t,r){return new(t||(t=Promise))((function(o,a){function i(e){try{u(r.next(e))}catch(n){a(n)}}function c(e){try{u(r.throw(e))}catch(n){a(n)}}function u(e){var n;e.done?o(e.value):(n=e.value,n instanceof t?n:new t((function(e){e(n)}))).then(i,c)}u((r=r.apply(e,n||[])).next())}))}function t(e,n){var t,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(c){return function(u){return function(c){if(t)throw new TypeError("Generator is already executing.");for(;a&&(a=0,c[0]&&(i=0)),i;)try{if(t=1,r&&(o=2&c[0]?r.return:c[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,c[1])).done)return o;switch(r=0,o&&(c=[2&c[0],o.value]),c[0]){case 0:case 1:o=c;break;case 4:return i.label++,{value:c[1],done:!1};case 5:i.label++,r=c[1],c=[0];continue;case 7:c=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==c[0]&&2!==c[0])){i=0;continue}if(3===c[0]&&(!o||c[1]>o[0]&&c[1]<o[3])){i.label=c[1];break}if(6===c[0]&&i.label<o[1]){i.label=o[1],o=c;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(c);break}o[2]&&i.ops.pop(),i.trys.pop();continue}c=n.call(e,i)}catch(u){c=[6,u],r=0}finally{t=o=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,u])}}}function r(e,n,t){if(t||2===arguments.length)for(var r,o=0,a=n.length;o<a;o++)!r&&o in n||(r||(r=Array.prototype.slice.call(n,0,o)),r[o]=n[o]);return e.concat(r||Array.prototype.slice.call(n))}function o(e,n){return new Promise((function(t){return setTimeout(t,e,n)}))}function a(e){return!!e&&"function"==typeof e.then}function i(e,n){try{var t=e();a(t)?t.then((function(e){return n(!0,e)}),(function(e){return n(!1,e)})):n(!0,t)}catch(r){n(!1,r)}}function c(e,r,a){return void 0===a&&(a=16),n(this,void 0,void 0,(function(){var n,i,c,u;return t(this,(function(t){switch(t.label){case 0:n=Array(e.length),i=Date.now(),c=0,t.label=1;case 1:return c<e.length?(n[c]=r(e[c],c),(u=Date.now())>=i+a?(i=u,[4,o(0)]):[3,3]):[3,4];case 2:t.sent(),t.label=3;case 3:return++c,[3,1];case 4:return[2,n]}}))}))}function u(e){e.then(void 0,(function(){}))}function l(e,n){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],n=[n[0]>>>16,65535&n[0],n[1]>>>16,65535&n[1]];var t=[0,0,0,0];return t[3]+=e[3]+n[3],t[2]+=t[3]>>>16,t[3]&=65535,t[2]+=e[2]+n[2],t[1]+=t[2]>>>16,t[2]&=65535,t[1]+=e[1]+n[1],t[0]+=t[1]>>>16,t[1]&=65535,t[0]+=e[0]+n[0],t[0]&=65535,[t[0]<<16|t[1],t[2]<<16|t[3]]}function s(e,n){e=[e[0]>>>16,65535&e[0],e[1]>>>16,65535&e[1]],n=[n[0]>>>16,65535&n[0],n[1]>>>16,65535&n[1]];var t=[0,0,0,0];return t[3]+=e[3]*n[3],t[2]+=t[3]>>>16,t[3]&=65535,t[2]+=e[2]*n[3],t[1]+=t[2]>>>16,t[2]&=65535,t[2]+=e[3]*n[2],t[1]+=t[2]>>>16,t[2]&=65535,t[1]+=e[1]*n[3],t[0]+=t[1]>>>16,t[1]&=65535,t[1]+=e[2]*n[2],t[0]+=t[1]>>>16,t[1]&=65535,t[1]+=e[3]*n[1],t[0]+=t[1]>>>16,t[1]&=65535,t[0]+=e[0]*n[3]+e[1]*n[2]+e[2]*n[1]+e[3]*n[0],t[0]&=65535,[t[0]<<16|t[1],t[2]<<16|t[3]]}function d(e,n){return 32===(n%=64)?[e[1],e[0]]:n<32?[e[0]<<n|e[1]>>>32-n,e[1]<<n|e[0]>>>32-n]:(n-=32,[e[1]<<n|e[0]>>>32-n,e[0]<<n|e[1]>>>32-n])}function m(e,n){return 0===(n%=64)?e:n<32?[e[0]<<n|e[1]>>>32-n,e[1]<<n]:[e[1]<<n-32,0]}function f(e,n){return[e[0]^n[0],e[1]^n[1]]}function v(e){return e=f(e,[0,e[0]>>>1]),e=f(e=s(e,[4283543511,3981806797]),[0,e[0]>>>1]),e=f(e=s(e,[3301882366,444984403]),[0,e[0]>>>1])}function h(e,n){n=n||0;var t,r=(e=e||"").length%16,o=e.length-r,a=[0,n],i=[0,n],c=[0,0],u=[0,0],h=[2277735313,289559509],p=[1291169091,658871167];for(t=0;t<o;t+=16)c=[255&e.charCodeAt(t+4)|(255&e.charCodeAt(t+5))<<8|(255&e.charCodeAt(t+6))<<16|(255&e.charCodeAt(t+7))<<24,255&e.charCodeAt(t)|(255&e.charCodeAt(t+1))<<8|(255&e.charCodeAt(t+2))<<16|(255&e.charCodeAt(t+3))<<24],u=[255&e.charCodeAt(t+12)|(255&e.charCodeAt(t+13))<<8|(255&e.charCodeAt(t+14))<<16|(255&e.charCodeAt(t+15))<<24,255&e.charCodeAt(t+8)|(255&e.charCodeAt(t+9))<<8|(255&e.charCodeAt(t+10))<<16|(255&e.charCodeAt(t+11))<<24],c=d(c=s(c,h),31),a=l(a=d(a=f(a,c=s(c,p)),27),i),a=l(s(a,[0,5]),[0,1390208809]),u=d(u=s(u,p),33),i=l(i=d(i=f(i,u=s(u,h)),31),a),i=l(s(i,[0,5]),[0,944331445]);switch(c=[0,0],u=[0,0],r){case 15:u=f(u,m([0,e.charCodeAt(t+14)],48));case 14:u=f(u,m([0,e.charCodeAt(t+13)],40));case 13:u=f(u,m([0,e.charCodeAt(t+12)],32));case 12:u=f(u,m([0,e.charCodeAt(t+11)],24));case 11:u=f(u,m([0,e.charCodeAt(t+10)],16));case 10:u=f(u,m([0,e.charCodeAt(t+9)],8));case 9:u=s(u=f(u,[0,e.charCodeAt(t+8)]),p),i=f(i,u=s(u=d(u,33),h));case 8:c=f(c,m([0,e.charCodeAt(t+7)],56));case 7:c=f(c,m([0,e.charCodeAt(t+6)],48));case 6:c=f(c,m([0,e.charCodeAt(t+5)],40));case 5:c=f(c,m([0,e.charCodeAt(t+4)],32));case 4:c=f(c,m([0,e.charCodeAt(t+3)],24));case 3:c=f(c,m([0,e.charCodeAt(t+2)],16));case 2:c=f(c,m([0,e.charCodeAt(t+1)],8));case 1:c=s(c=f(c,[0,e.charCodeAt(t)]),h),a=f(a,c=s(c=d(c,31),p))}return a=l(a=f(a,[0,e.length]),i=f(i,[0,e.length])),i=l(i,a),a=l(a=v(a),i=v(i)),i=l(i,a),("00000000"+(a[0]>>>0).toString(16)).slice(-8)+("00000000"+(a[1]>>>0).toString(16)).slice(-8)+("00000000"+(i[0]>>>0).toString(16)).slice(-8)+("00000000"+(i[1]>>>0).toString(16)).slice(-8)}function p(e){return parseInt(e)}function b(e){return parseFloat(e)}function y(e,n){return"number"==typeof e&&isNaN(e)?n:e}function g(e){return e.reduce((function(e,n){return e+(n?1:0)}),0)}function w(e,n){if(void 0===n&&(n=1),Math.abs(n)>=1)return Math.round(e/n)*n;var t=1/n;return Math.round(e*t)/t}function L(e){return e&&"object"==typeof e&&"message"in e?e:{message:e}}function k(e){return"function"!=typeof e}function V(e,r,o){var a=Object.keys(e).filter((function(e){return!function(e,n){for(var t=0,r=e.length;t<r;++t)if(e[t]===n)return!0;return!1}(o,e)})),l=c(a,(function(n){return function(e,n){var t=new Promise((function(t){var r=Date.now();i(e.bind(null,n),(function(){for(var e=[],n=0;n<arguments.length;n++)e[n]=arguments[n];var o=Date.now()-r;if(!e[0])return t((function(){return{error:L(e[1]),duration:o}}));var a=e[1];if(k(a))return t((function(){return{value:a,duration:o}}));t((function(){return new Promise((function(e){var n=Date.now();i(a,(function(){for(var t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];var a=o+Date.now()-n;if(!t[0])return e({error:L(t[1]),duration:a});e({value:t[1],duration:a})}))}))}))}))}));return u(t),function(){return t.then((function(e){return e()}))}}(e[n],r)}));return u(l),function(){return n(this,void 0,void 0,(function(){var e,n,r,o;return t(this,(function(t){switch(t.label){case 0:return[4,l];case 1:return[4,c(t.sent(),(function(e){var n=e();return u(n),n}))];case 2:return e=t.sent(),[4,Promise.all(e)];case 3:for(n=t.sent(),r={},o=0;o<a.length;++o)r[a[o]]=n[o];return[2,r]}}))}))}}function Z(e,n){var t=function(e){return k(e)?n(e):function(){var t=e();return a(t)?t.then(n):n(t)}};return function(n){var r=e(n);return a(r)?r.then(t):t(r)}}function W(){var e=window,n=navigator;return g(["MSCSSMatrix"in e,"msSetImmediate"in e,"msIndexedDB"in e,"msMaxTouchPoints"in n,"msPointerEnabled"in n])>=4}function C(){var e=window,n=navigator;return g(["msWriteProfilerMark"in e,"MSStream"in e,"msLaunchUri"in n,"msSaveBlob"in n])>=3&&!W()}function S(){var e=window,n=navigator;return g(["webkitPersistentStorage"in n,"webkitTemporaryStorage"in n,0===n.vendor.indexOf("Google"),"webkitResolveLocalFileSystemURL"in e,"BatteryManager"in e,"webkitMediaStream"in e,"webkitSpeechGrammar"in e])>=5}function x(){var e=window,n=navigator;return g(["ApplePayError"in e,"CSSPrimitiveValue"in e,"Counter"in e,0===n.vendor.indexOf("Apple"),"getStorageUpdates"in n,"WebKitMediaKeys"in e])>=4}function F(){var e=window;return g(["safari"in e,!("DeviceMotionEvent"in e),!("ongestureend"in e),!("standalone"in navigator)])>=3}function Y(){var e,n,t=window;return g(["buildID"in navigator,"MozAppearance"in(null!==(n=null===(e=document.documentElement)||void 0===e?void 0:e.style)&&void 0!==n?n:{}),"onmozfullscreenchange"in t,"mozInnerScreenX"in t,"CSSMozDocumentRule"in t,"CanvasCaptureMediaStream"in t])>=4}function M(){var e=document;return e.fullscreenElement||e.msFullscreenElement||e.mozFullScreenElement||e.webkitFullscreenElement||null}function G(){var e=S(),n=Y();if(!e&&!n)return!1;var t=window;return g(["onorientationchange"in t,"orientation"in t,e&&!("SharedWorker"in t),n&&/android/i.test(navigator.appVersion)])>=2}function R(e){var n=new Error(e);return n.name=e,n}function X(e,r,a){var i,c,u;return void 0===a&&(a=50),n(this,void 0,void 0,(function(){var n,l;return t(this,(function(t){switch(t.label){case 0:n=document,t.label=1;case 1:return n.body?[3,3]:[4,o(a)];case 2:return t.sent(),[3,1];case 3:l=n.createElement("iframe"),t.label=4;case 4:return t.trys.push([4,,10,11]),[4,new Promise((function(e,t){var o=!1,a=function(){o=!0,e()};l.onload=a,l.onerror=function(e){o=!0,t(e)};var i=l.style;i.setProperty("display","block","important"),i.position="absolute",i.top="0",i.left="0",i.visibility="hidden",r&&"srcdoc"in l?l.srcdoc=r:l.src="about:blank",n.body.appendChild(l);var c=function(){var e,n;o||("complete"===(null===(n=null===(e=l.contentWindow)||void 0===e?void 0:e.document)||void 0===n?void 0:n.readyState)?a():setTimeout(c,10))};c()}))];case 5:t.sent(),t.label=6;case 6:return(null===(c=null===(i=l.contentWindow)||void 0===i?void 0:i.document)||void 0===c?void 0:c.body)?[3,8]:[4,o(a)];case 7:return t.sent(),[3,6];case 8:return[4,e(l,l.contentWindow)];case 9:return[2,t.sent()];case 10:return null===(u=l.parentNode)||void 0===u||u.removeChild(l),[7];case 11:return[2]}}))}))}function A(e){for(var n=function(e){for(var n,t,r="Unexpected syntax '".concat(e,"'"),o=/^\s*([a-z-]*)(.*)$/i.exec(e),a=o[1]||void 0,i={},c=/([.:#][\w-]+|\[.+?\])/gi,u=function(e,n){i[e]=i[e]||[],i[e].push(n)};;){var l=c.exec(o[2]);if(!l)break;var s=l[0];switch(s[0]){case".":u("class",s.slice(1));break;case"#":u("id",s.slice(1));break;case"[":var d=/^\[([\w-]+)([~|^$*]?=("(.*?)"|([\w-]+)))?(\s+[is])?\]$/.exec(s);if(!d)throw new Error(r);u(d[1],null!==(t=null!==(n=d[4])&&void 0!==n?n:d[5])&&void 0!==t?t:"");break;default:throw new Error(r)}}return[a,i]}(e),t=n[0],r=n[1],o=document.createElement(null!=t?t:"div"),a=0,i=Object.keys(r);a<i.length;a++){var c=i[a],u=r[c].join(" ");"style"===c?j(o.style,u):o.setAttribute(c,u)}return o}function j(e,n){for(var t=0,r=n.split(";");t<r.length;t++){var o=r[t],a=/^\s*([\w-]+)\s*:\s*(.+?)(\s*!([\w-]+))?\s*$/.exec(o);if(a){var i=a[1],c=a[2],u=a[4];e.setProperty(i,c,u||"")}}}var I=["monospace","sans-serif","serif"],J=["sans-serif-thin","ARNO PRO","Agency FB","Arabic Typesetting","Arial Unicode MS","AvantGarde Bk BT","BankGothic Md BT","Batang","Bitstream Vera Sans Mono","Calibri","Century","Century Gothic","Clarendon","EUROSTILE","Franklin Gothic","Futura Bk BT","Futura Md BT","GOTHAM","Gill Sans","HELV","Haettenschweiler","Helvetica Neue","Humanst521 BT","Leelawadee","Letter Gothic","Levenim MT","Lucida Bright","Lucida Sans","Menlo","MS Mincho","MS Outlook","MS Reference Specialty","MS UI Gothic","MT Extra","MYRIAD PRO","Marlett","Meiryo UI","Microsoft Uighur","Minion Pro","Monotype Corsiva","PMingLiU","Pristina","SCRIPTINA","Segoe UI Light","Serifa","SimHei","Small Fonts","Staccato222 BT","TRAJAN PRO","Univers CE 55 Medium","Vrinda","ZWAdobeF"];function H(e){return e.toDataURL()}var P,N;function z(){var e=this;return function(){if(void 0===N){var e=function(){var n=D();E(n)?N=setTimeout(e,2500):(P=n,N=void 0)};e()}}(),function(){return n(e,void 0,void 0,(function(){var e;return t(this,(function(n){switch(n.label){case 0:return E(e=D())?P?[2,r([],P,!0)]:M()?[4,(t=document,(t.exitFullscreen||t.msExitFullscreen||t.mozCancelFullScreen||t.webkitExitFullscreen).call(t))]:[3,2]:[3,2];case 1:n.sent(),e=D(),n.label=2;case 2:return E(e)||(P=e),[2,e]}var t}))}))}}function D(){var e=screen;return[y(b(e.availTop),null),y(b(e.width)-b(e.availWidth)-y(b(e.availLeft),0),null),y(b(e.height)-b(e.availHeight)-y(b(e.availTop),0),null),y(b(e.availLeft),null)]}function E(e){for(var n=0;n<4;++n)if(e[n])return!1;return!0}function T(e){var r;return n(this,void 0,void 0,(function(){var n,a,i,c,u,l,s;return t(this,(function(t){switch(t.label){case 0:for(n=document,a=n.createElement("div"),i=new Array(e.length),c={},B(a),s=0;s<e.length;++s)"DIALOG"===(u=A(e[s])).tagName&&u.show(),B(l=n.createElement("div")),l.appendChild(u),a.appendChild(l),i[s]=u;t.label=1;case 1:return n.body?[3,3]:[4,o(50)];case 2:return t.sent(),[3,1];case 3:n.body.appendChild(a);try{for(s=0;s<e.length;++s)i[s].offsetParent||(c[e[s]]=!0)}finally{null===(r=a.parentNode)||void 0===r||r.removeChild(a)}return[2,c]}}))}))}function B(e){e.style.setProperty("display","block","important")}function _(e){return matchMedia("(inverted-colors: ".concat(e,")")).matches}function O(e){return matchMedia("(forced-colors: ".concat(e,")")).matches}function U(e){return matchMedia("(prefers-contrast: ".concat(e,")")).matches}function Q(e){return matchMedia("(prefers-reduced-motion: ".concat(e,")")).matches}function K(e){return matchMedia("(dynamic-range: ".concat(e,")")).matches}var q=Math,$=function(){return 0};var ee={default:[],apple:[{font:"-apple-system-body"}],serif:[{fontFamily:"serif"}],sans:[{fontFamily:"sans-serif"}],mono:[{fontFamily:"monospace"}],min:[{fontSize:"1px"}],system:[{fontFamily:"system-ui"}]};var ne={fonts:function(){return X((function(e,n){var t=n.document,r=t.body;r.style.fontSize="48px";var o=t.createElement("div"),a={},i={},c=function(e){var n=t.createElement("span"),r=n.style;return r.position="absolute",r.top="0",r.left="0",r.fontFamily=e,n.textContent="mmMwWLliI0O&1",o.appendChild(n),n},u=I.map(c),l=function(){for(var e={},n=function(n){e[n]=I.map((function(e){return function(e,n){return c("'".concat(e,"',").concat(n))}(n,e)}))},t=0,r=J;t<r.length;t++){n(r[t])}return e}();r.appendChild(o);for(var s=0;s<I.length;s++)a[I[s]]=u[s].offsetWidth,i[I[s]]=u[s].offsetHeight;return J.filter((function(e){return n=l[e],I.some((function(e,t){return n[t].offsetWidth!==a[e]||n[t].offsetHeight!==i[e]}));var n}))}))},domBlockers:function(e){var r=(void 0===e?{}:e).debug;return n(this,void 0,void 0,(function(){var e,n,o,a,i;return t(this,(function(t){switch(t.label){case 0:return x()||G()?(c=atob,e={abpIndo:["#Iklan-Melayang","#Kolom-Iklan-728","#SidebarIklan-wrapper",'[title="ALIENBOLA" i]',c("I0JveC1CYW5uZXItYWRz")],abpvn:[".quangcao","#mobileCatfish",c("LmNsb3NlLWFkcw=="),'[id^="bn_bottom_fixed_"]',"#pmadv"],adBlockFinland:[".mainostila",c("LnNwb25zb3JpdA=="),".ylamainos",c("YVtocmVmKj0iL2NsaWNrdGhyZ2guYXNwPyJd"),c("YVtocmVmXj0iaHR0cHM6Ly9hcHAucmVhZHBlYWsuY29tL2FkcyJd")],adBlockPersian:["#navbar_notice_50",".kadr",'TABLE[width="140px"]',"#divAgahi",c("YVtocmVmXj0iaHR0cDovL2cxLnYuZndtcm0ubmV0L2FkLyJd")],adBlockWarningRemoval:["#adblock-honeypot",".adblocker-root",".wp_adblock_detect",c("LmhlYWRlci1ibG9ja2VkLWFk"),c("I2FkX2Jsb2NrZXI=")],adGuardAnnoyances:[".hs-sosyal","#cookieconsentdiv",'div[class^="app_gdpr"]',".as-oil",'[data-cypress="soft-push-notification-modal"]'],adGuardBase:[".BetterJsPopOverlay",c("I2FkXzMwMFgyNTA="),c("I2Jhbm5lcmZsb2F0MjI="),c("I2NhbXBhaWduLWJhbm5lcg=="),c("I0FkLUNvbnRlbnQ=")],adGuardChinese:[c("LlppX2FkX2FfSA=="),c("YVtocmVmKj0iLmh0aGJldDM0LmNvbSJd"),"#widget-quan",c("YVtocmVmKj0iLzg0OTkyMDIwLnh5eiJd"),c("YVtocmVmKj0iLjE5NTZobC5jb20vIl0=")],adGuardFrench:["#pavePub",c("LmFkLWRlc2t0b3AtcmVjdGFuZ2xl"),".mobile_adhesion",".widgetadv",c("LmFkc19iYW4=")],adGuardGerman:['aside[data-portal-id="leaderboard"]'],adGuardJapanese:["#kauli_yad_1",c("YVtocmVmXj0iaHR0cDovL2FkMi50cmFmZmljZ2F0ZS5uZXQvIl0="),c("Ll9wb3BJbl9pbmZpbml0ZV9hZA=="),c("LmFkZ29vZ2xl"),c("Ll9faXNib29zdFJldHVybkFk")],adGuardMobile:[c("YW1wLWF1dG8tYWRz"),c("LmFtcF9hZA=="),'amp-embed[type="24smi"]',"#mgid_iframe1",c("I2FkX2ludmlld19hcmVh")],adGuardRussian:[c("YVtocmVmXj0iaHR0cHM6Ly9hZC5sZXRtZWFkcy5jb20vIl0="),c("LnJlY2xhbWE="),'div[id^="smi2adblock"]',c("ZGl2W2lkXj0iQWRGb3hfYmFubmVyXyJd"),"#psyduckpockeball"],adGuardSocial:[c("YVtocmVmXj0iLy93d3cuc3R1bWJsZXVwb24uY29tL3N1Ym1pdD91cmw9Il0="),c("YVtocmVmXj0iLy90ZWxlZ3JhbS5tZS9zaGFyZS91cmw/Il0="),".etsy-tweet","#inlineShare",".popup-social"],adGuardSpanishPortuguese:["#barraPublicidade","#Publicidade","#publiEspecial","#queTooltip",".cnt-publi"],adGuardTrackingProtection:["#qoo-counter",c("YVtocmVmXj0iaHR0cDovL2NsaWNrLmhvdGxvZy5ydS8iXQ=="),c("YVtocmVmXj0iaHR0cDovL2hpdGNvdW50ZXIucnUvdG9wL3N0YXQucGhwIl0="),c("YVtocmVmXj0iaHR0cDovL3RvcC5tYWlsLnJ1L2p1bXAiXQ=="),"#top100counter"],adGuardTurkish:["#backkapat",c("I3Jla2xhbWk="),c("YVtocmVmXj0iaHR0cDovL2Fkc2Vydi5vbnRlay5jb20udHIvIl0="),c("YVtocmVmXj0iaHR0cDovL2l6bGVuemkuY29tL2NhbXBhaWduLyJd"),c("YVtocmVmXj0iaHR0cDovL3d3dy5pbnN0YWxsYWRzLm5ldC8iXQ==")],bulgarian:[c("dGQjZnJlZW5ldF90YWJsZV9hZHM="),"#ea_intext_div",".lapni-pop-over","#xenium_hot_offers"],easyList:[".yb-floorad",c("LndpZGdldF9wb19hZHNfd2lkZ2V0"),c("LnRyYWZmaWNqdW5reS1hZA=="),".textad_headline",c("LnNwb25zb3JlZC10ZXh0LWxpbmtz")],easyListChina:[c("LmFwcGd1aWRlLXdyYXBbb25jbGljayo9ImJjZWJvcy5jb20iXQ=="),c("LmZyb250cGFnZUFkdk0="),"#taotaole","#aafoot.top_box",".cfa_popup"],easyListCookie:[".ezmob-footer",".cc-CookieWarning","[data-cookie-number]",c("LmF3LWNvb2tpZS1iYW5uZXI="),".sygnal24-gdpr-modal-wrap"],easyListCzechSlovak:["#onlajny-stickers",c("I3Jla2xhbW5pLWJveA=="),c("LnJla2xhbWEtbWVnYWJvYXJk"),".sklik",c("W2lkXj0ic2tsaWtSZWtsYW1hIl0=")],easyListDutch:[c("I2FkdmVydGVudGll"),c("I3ZpcEFkbWFya3RCYW5uZXJCbG9jaw=="),".adstekst",c("YVtocmVmXj0iaHR0cHM6Ly94bHR1YmUubmwvY2xpY2svIl0="),"#semilo-lrectangle"],easyListGermany:["#SSpotIMPopSlider",c("LnNwb25zb3JsaW5rZ3J1ZW4="),c("I3dlcmJ1bmdza3k="),c("I3Jla2xhbWUtcmVjaHRzLW1pdHRl"),c("YVtocmVmXj0iaHR0cHM6Ly9iZDc0Mi5jb20vIl0=")],easyListItaly:[c("LmJveF9hZHZfYW5udW5jaQ=="),".sb-box-pubbliredazionale",c("YVtocmVmXj0iaHR0cDovL2FmZmlsaWF6aW9uaWFkcy5zbmFpLml0LyJd"),c("YVtocmVmXj0iaHR0cHM6Ly9hZHNlcnZlci5odG1sLml0LyJd"),c("YVtocmVmXj0iaHR0cHM6Ly9hZmZpbGlhemlvbmlhZHMuc25haS5pdC8iXQ==")],easyListLithuania:[c("LnJla2xhbW9zX3RhcnBhcw=="),c("LnJla2xhbW9zX251b3JvZG9z"),c("aW1nW2FsdD0iUmVrbGFtaW5pcyBza3lkZWxpcyJd"),c("aW1nW2FsdD0iRGVkaWt1b3RpLmx0IHNlcnZlcmlhaSJd"),c("aW1nW2FsdD0iSG9zdGluZ2FzIFNlcnZlcmlhaS5sdCJd")],estonian:[c("QVtocmVmKj0iaHR0cDovL3BheTRyZXN1bHRzMjQuZXUiXQ==")],fanboyAnnoyances:["#ac-lre-player",".navigate-to-top","#subscribe_popup",".newsletter_holder","#back-top"],fanboyAntiFacebook:[".util-bar-module-firefly-visible"],fanboyEnhancedTrackers:[".open.pushModal","#issuem-leaky-paywall-articles-zero-remaining-nag","#sovrn_container",'div[class$="-hide"][zoompage-fontsize][style="display: block;"]',".BlockNag__Card"],fanboySocial:["#FollowUs","#meteored_share","#social_follow",".article-sharer",".community__social-desc"],frellwitSwedish:[c("YVtocmVmKj0iY2FzaW5vcHJvLnNlIl1bdGFyZ2V0PSJfYmxhbmsiXQ=="),c("YVtocmVmKj0iZG9rdG9yLXNlLm9uZWxpbmsubWUiXQ=="),"article.category-samarbete",c("ZGl2LmhvbGlkQWRz"),"ul.adsmodern"],greekAdBlock:[c("QVtocmVmKj0iYWRtYW4ub3RlbmV0LmdyL2NsaWNrPyJd"),c("QVtocmVmKj0iaHR0cDovL2F4aWFiYW5uZXJzLmV4b2R1cy5nci8iXQ=="),c("QVtocmVmKj0iaHR0cDovL2ludGVyYWN0aXZlLmZvcnRobmV0LmdyL2NsaWNrPyJd"),"DIV.agores300","TABLE.advright"],hungarian:["#cemp_doboz",".optimonk-iframe-container",c("LmFkX19tYWlu"),c("W2NsYXNzKj0iR29vZ2xlQWRzIl0="),"#hirdetesek_box"],iDontCareAboutCookies:['.alert-info[data-block-track*="CookieNotice"]',".ModuleTemplateCookieIndicator",".o--cookies--container","#cookies-policy-sticky","#stickyCookieBar"],icelandicAbp:[c("QVtocmVmXj0iL2ZyYW1ld29yay9yZXNvdXJjZXMvZm9ybXMvYWRzLmFzcHgiXQ==")],latvian:[c("YVtocmVmPSJodHRwOi8vd3d3LnNhbGlkemluaS5sdi8iXVtzdHlsZT0iZGlzcGxheTogYmxvY2s7IHdpZHRoOiAxMjBweDsgaGVpZ2h0OiA0MHB4OyBvdmVyZmxvdzogaGlkZGVuOyBwb3NpdGlvbjogcmVsYXRpdmU7Il0="),c("YVtocmVmPSJodHRwOi8vd3d3LnNhbGlkemluaS5sdi8iXVtzdHlsZT0iZGlzcGxheTogYmxvY2s7IHdpZHRoOiA4OHB4OyBoZWlnaHQ6IDMxcHg7IG92ZXJmbG93OiBoaWRkZW47IHBvc2l0aW9uOiByZWxhdGl2ZTsiXQ==")],listKr:[c("YVtocmVmKj0iLy9hZC5wbGFuYnBsdXMuY28ua3IvIl0="),c("I2xpdmVyZUFkV3JhcHBlcg=="),c("YVtocmVmKj0iLy9hZHYuaW1hZHJlcC5jby5rci8iXQ=="),c("aW5zLmZhc3R2aWV3LWFk"),".revenue_unit_item.dable"],listeAr:[c("LmdlbWluaUxCMUFk"),".right-and-left-sponsers",c("YVtocmVmKj0iLmFmbGFtLmluZm8iXQ=="),c("YVtocmVmKj0iYm9vcmFxLm9yZyJd"),c("YVtocmVmKj0iZHViaXp6bGUuY29tL2FyLz91dG1fc291cmNlPSJd")],listeFr:[c("YVtocmVmXj0iaHR0cDovL3Byb21vLnZhZG9yLmNvbS8iXQ=="),c("I2FkY29udGFpbmVyX3JlY2hlcmNoZQ=="),c("YVtocmVmKj0id2Vib3JhbWEuZnIvZmNnaS1iaW4vIl0="),".site-pub-interstitiel",'div[id^="crt-"][data-criteo-id]'],officialPolish:["#ceneo-placeholder-ceneo-12",c("W2hyZWZePSJodHRwczovL2FmZi5zZW5kaHViLnBsLyJd"),c("YVtocmVmXj0iaHR0cDovL2Fkdm1hbmFnZXIudGVjaGZ1bi5wbC9yZWRpcmVjdC8iXQ=="),c("YVtocmVmXj0iaHR0cDovL3d3dy50cml6ZXIucGwvP3V0bV9zb3VyY2UiXQ=="),c("ZGl2I3NrYXBpZWNfYWQ=")],ro:[c("YVtocmVmXj0iLy9hZmZ0cmsuYWx0ZXgucm8vQ291bnRlci9DbGljayJd"),c("YVtocmVmXj0iaHR0cHM6Ly9ibGFja2ZyaWRheXNhbGVzLnJvL3Ryay9zaG9wLyJd"),c("YVtocmVmXj0iaHR0cHM6Ly9ldmVudC4ycGVyZm9ybWFudC5jb20vZXZlbnRzL2NsaWNrIl0="),c("YVtocmVmXj0iaHR0cHM6Ly9sLnByb2ZpdHNoYXJlLnJvLyJd"),'a[href^="/url/"]'],ruAd:[c("YVtocmVmKj0iLy9mZWJyYXJlLnJ1LyJd"),c("YVtocmVmKj0iLy91dGltZy5ydS8iXQ=="),c("YVtocmVmKj0iOi8vY2hpa2lkaWtpLnJ1Il0="),"#pgeldiz",".yandex-rtb-block"],thaiAds:["a[href*=macau-uta-popup]",c("I2Fkcy1nb29nbGUtbWlkZGxlX3JlY3RhbmdsZS1ncm91cA=="),c("LmFkczMwMHM="),".bumq",".img-kosana"],webAnnoyancesUltralist:["#mod-social-share-2","#social-tools",c("LmN0cGwtZnVsbGJhbm5lcg=="),".zergnet-recommend",".yt.btn-link.btn-md.btn"]},n=Object.keys(e),[4,T((i=[]).concat.apply(i,n.map((function(n){return e[n]}))))]):[2,void 0];case 1:return o=t.sent(),r&&function(e,n){for(var t="DOM blockers debug:\n```",r=0,o=Object.keys(e);r<o.length;r++){var a=o[r];t+="\n".concat(a,":");for(var i=0,c=e[a];i<c.length;i++){var u=c[i];t+="\n ".concat(n[u]?"🚫":"➡️"," ").concat(u)}}console.log("".concat(t,"\n```"))}(e,o),(a=n.filter((function(n){var t=e[n];return g(t.map((function(e){return o[e]})))>.6*t.length}))).sort(),[2,a]}var c}))}))},fontPreferences:function(){return function(e,n){void 0===n&&(n=4e3);return X((function(t,o){var a=o.document,i=a.body,c=i.style;c.width="".concat(n,"px"),c.webkitTextSizeAdjust=c.textSizeAdjust="none",S()?i.style.zoom="".concat(1/o.devicePixelRatio):x()&&(i.style.zoom="reset");var u=a.createElement("div");return u.textContent=r([],Array(n/20<<0),!0).map((function(){return"word"})).join(" "),i.appendChild(u),e(a,i)}),'<!doctype html><html><head><meta name="viewport" content="width=device-width, initial-scale=1">')}((function(e,n){for(var t={},r={},o=0,a=Object.keys(ee);o<a.length;o++){var i=a[o],c=ee[i],u=c[0],l=void 0===u?{}:u,s=c[1],d=void 0===s?"mmMwWLliI0fiflO&1":s,m=e.createElement("span");m.textContent=d,m.style.whiteSpace="nowrap";for(var f=0,v=Object.keys(l);f<v.length;f++){var h=v[f],p=l[h];void 0!==p&&(m.style[h]=p)}t[i]=m,n.appendChild(e.createElement("br")),n.appendChild(m)}for(var b=0,y=Object.keys(ee);b<y.length;b++){r[i=y[b]]=t[i].getBoundingClientRect().width}return r}))},audio:function(){var e=window,n=e.OfflineAudioContext||e.webkitOfflineAudioContext;if(!n)return-2;if(x()&&!F()&&!function(){var e=window;return g(["DOMRectList"in e,"RTCPeerConnectionIceEvent"in e,"SVGGeometryElement"in e,"ontransitioncancel"in e])>=3}())return-1;var t=new n(1,5e3,44100),r=t.createOscillator();r.type="triangle",r.frequency.value=1e4;var o=t.createDynamicsCompressor();o.threshold.value=-50,o.knee.value=40,o.ratio.value=12,o.attack.value=0,o.release.value=.25,r.connect(o),o.connect(t.destination),r.start(0);var i=function(e){var n=3,t=500,r=500,o=5e3,i=function(){};return[new Promise((function(c,l){var s=!1,d=0,m=0;e.oncomplete=function(e){return c(e.renderedBuffer)};var f=function(){setTimeout((function(){return l(R("timeout"))}),Math.min(r,m+o-Date.now()))},v=function(){try{var r=e.startRendering();switch(a(r)&&u(r),e.state){case"running":m=Date.now(),s&&f();break;case"suspended":document.hidden||d++,s&&d>=n?l(R("suspended")):setTimeout(v,t)}}catch(o){l(o)}};v(),i=function(){s||(s=!0,m>0&&f())}})),i]}(t),c=i[0],l=i[1],s=c.then((function(e){return function(e){for(var n=0,t=0;t<e.length;++t)n+=Math.abs(e[t]);return n}(e.getChannelData(0).subarray(4500))}),(function(e){if("timeout"===e.name||"suspended"===e.name)return-3;throw e}));return u(s),function(){return l(),s}},screenFrame:function(){var e=this,r=z();return function(){return n(e,void 0,void 0,(function(){var e,n;return t(this,(function(t){switch(t.label){case 0:return[4,r()];case 1:return e=t.sent(),[2,[(n=function(e){return null===e?null:w(e,10)})(e[0]),n(e[1]),n(e[2]),n(e[3])]]}}))}))}},osCpu:function(){return navigator.oscpu},languages:function(){var e,n=navigator,t=[],r=n.language||n.userLanguage||n.browserLanguage||n.systemLanguage;if(void 0!==r&&t.push([r]),Array.isArray(n.languages))S()&&g([!("MediaSettingsRange"in(e=window)),"RTCEncodedAudioFrame"in e,""+e.Intl=="[object Intl]",""+e.Reflect=="[object Reflect]"])>=3||t.push(n.languages);else if("string"==typeof n.languages){var o=n.languages;o&&t.push(o.split(","))}return t},colorDepth:function(){return window.screen.colorDepth},deviceMemory:function(){return y(b(navigator.deviceMemory),void 0)},screenResolution:function(){var e=screen,n=function(e){return y(p(e),null)},t=[n(e.width),n(e.height)];return t.sort().reverse(),t},hardwareConcurrency:function(){return y(p(navigator.hardwareConcurrency),void 0)},timezone:function(){var e,n=null===(e=window.Intl)||void 0===e?void 0:e.DateTimeFormat;if(n){var t=(new n).resolvedOptions().timeZone;if(t)return t}var r,o=(r=(new Date).getFullYear(),-Math.max(b(new Date(r,0,1).getTimezoneOffset()),b(new Date(r,6,1).getTimezoneOffset())));return"UTC".concat(o>=0?"+":"").concat(Math.abs(o))},sessionStorage:function(){try{return!!window.sessionStorage}catch(e){return!0}},localStorage:function(){try{return!!window.localStorage}catch(e){return!0}},indexedDB:function(){if(!W()&&!C())try{return!!window.indexedDB}catch(e){return!0}},openDatabase:function(){return!!window.openDatabase},cpuClass:function(){return navigator.cpuClass},platform:function(){var e=navigator.platform;return"MacIntel"===e&&x()&&!F()?function(){if("iPad"===navigator.platform)return!0;var e=screen,n=e.width/e.height;return g(["MediaSource"in window,!!Element.prototype.webkitRequestFullscreen,n>.65&&n<1.53])>=2}()?"iPad":"iPhone":e},plugins:function(){var e=navigator.plugins;if(e){for(var n=[],t=0;t<e.length;++t){var r=e[t];if(r){for(var o=[],a=0;a<r.length;++a){var i=r[a];o.push({type:i.type,suffixes:i.suffixes})}n.push({name:r.name,description:r.description,mimeTypes:o})}}return n}},canvas:function(){var e,n,t=!1,r=function(){var e=document.createElement("canvas");return e.width=1,e.height=1,[e,e.getContext("2d")]}(),o=r[0],a=r[1];if(function(e,n){return!(!n||!e.toDataURL)}(o,a)){t=function(e){return e.rect(0,0,10,10),e.rect(2,2,6,6),!e.isPointInPath(5,5,"evenodd")}(a),function(e,n){e.width=240,e.height=60,n.textBaseline="alphabetic",n.fillStyle="#f60",n.fillRect(100,1,62,20),n.fillStyle="#069",n.font='11pt "Times New Roman"';var t="Cwm fjordbank gly ".concat(String.fromCharCode(55357,56835));n.fillText(t,2,15),n.fillStyle="rgba(102, 204, 0, 0.2)",n.font="18pt Arial",n.fillText(t,4,45)}(o,a);var i=H(o);i!==H(o)?e=n="unstable":(n=i,function(e,n){e.width=122,e.height=110,n.globalCompositeOperation="multiply";for(var t=0,r=[["#f2f",40,40],["#2ff",80,40],["#ff2",60,80]];t<r.length;t++){var o=r[t],a=o[0],i=o[1],c=o[2];n.fillStyle=a,n.beginPath(),n.arc(i,c,40,0,2*Math.PI,!0),n.closePath(),n.fill()}n.fillStyle="#f9c",n.arc(60,60,60,0,2*Math.PI,!0),n.arc(60,60,20,0,2*Math.PI,!0),n.fill("evenodd")}(o,a),e=H(o))}else e=n="";return{winding:t,geometry:e,text:n}},touchSupport:function(){var e,n=navigator,t=0;void 0!==n.maxTouchPoints?t=p(n.maxTouchPoints):void 0!==n.msMaxTouchPoints&&(t=n.msMaxTouchPoints);try{document.createEvent("TouchEvent"),e=!0}catch(r){e=!1}return{maxTouchPoints:t,touchEvent:e,touchStart:"ontouchstart"in window}},vendor:function(){return navigator.vendor||""},vendorFlavors:function(){for(var e=[],n=0,t=["chrome","safari","__crWeb","__gCrWeb","yandex","__yb","__ybro","__firefox__","__edgeTrackingPreventionStatistics","webkit","oprt","samsungAr","ucweb","UCShellJava","puffinDevice"];n<t.length;n++){var r=t[n],o=window[r];o&&"object"==typeof o&&e.push(r)}return e.sort()},cookiesEnabled:function(){var e=document;try{e.cookie="cookietest=1; SameSite=Strict;";var n=-1!==e.cookie.indexOf("cookietest=");return e.cookie="cookietest=1; SameSite=Strict; expires=Thu, 01-Jan-1970 00:00:01 GMT",n}catch(t){return!1}},colorGamut:function(){for(var e=0,n=["rec2020","p3","srgb"];e<n.length;e++){var t=n[e];if(matchMedia("(color-gamut: ".concat(t,")")).matches)return t}},invertedColors:function(){return!!_("inverted")||!_("none")&&void 0},forcedColors:function(){return!!O("active")||!O("none")&&void 0},monochrome:function(){if(matchMedia("(min-monochrome: 0)").matches){for(var e=0;e<=100;++e)if(matchMedia("(max-monochrome: ".concat(e,")")).matches)return e;throw new Error("Too high value")}},contrast:function(){return U("no-preference")?0:U("high")||U("more")?1:U("low")||U("less")?-1:U("forced")?10:void 0},reducedMotion:function(){return!!Q("reduce")||!Q("no-preference")&&void 0},hdr:function(){return!!K("high")||!K("standard")&&void 0},math:function(){var e,n=q.acos||$,t=q.acosh||$,r=q.asin||$,o=q.asinh||$,a=q.atanh||$,i=q.atan||$,c=q.sin||$,u=q.sinh||$,l=q.cos||$,s=q.cosh||$,d=q.tan||$,m=q.tanh||$,f=q.exp||$,v=q.expm1||$,h=q.log1p||$;return{acos:n(.12312423423423424),acosh:t(1e308),acoshPf:(e=1e154,q.log(e+q.sqrt(e*e-1))),asin:r(.12312423423423424),asinh:o(1),asinhPf:function(e){return q.log(e+q.sqrt(e*e+1))}(1),atanh:a(.5),atanhPf:function(e){return q.log((1+e)/(1-e))/2}(.5),atan:i(.5),sin:c(-1e300),sinh:u(1),sinhPf:function(e){return q.exp(e)-1/q.exp(e)/2}(1),cos:l(10.000000000123),cosh:s(1),coshPf:function(e){return(q.exp(e)+1/q.exp(e))/2}(1),tan:d(-1e300),tanh:m(1),tanhPf:function(e){return(q.exp(2*e)-1)/(q.exp(2*e)+1)}(1),exp:f(1),expm1:v(1),expm1Pf:function(e){return q.exp(e)-1}(1),log1p:h(10),log1pPf:function(e){return q.log(1+e)}(10),powPI:function(e){return q.pow(q.PI,e)}(-100)}},videoCard:function(){var e,n=document.createElement("canvas"),t=null!==(e=n.getContext("webgl"))&&void 0!==e?e:n.getContext("experimental-webgl");if(t&&"getExtension"in t){var r=t.getExtension("WEBGL_debug_renderer_info");if(r)return{vendor:(t.getParameter(r.UNMASKED_VENDOR_WEBGL)||"").toString(),renderer:(t.getParameter(r.UNMASKED_RENDERER_WEBGL)||"").toString()}}},pdfViewerEnabled:function(){return navigator.pdfViewerEnabled},architecture:function(){var e=new Float32Array(1),n=new Uint8Array(e.buffer);return e[0]=1/0,e[0]=e[0]-e[0],n[3]}};function te(e){var n=function(e){if(G())return.4;if(x())return F()?.5:.3;var n=e.platform.value||"";if(/^Win/.test(n))return.6;if(/^Mac/.test(n))return.5;return.7}(e),t=function(e){return w(.99+.01*e,1e-4)}(n);return{score:n,comment:"$ if upgrade to Pro: https://fpjs.dev/pro".replace(/\$/g,"".concat(t))}}function re(n){return JSON.stringify(n,(function(n,t){return t instanceof Error?e({name:(r=t).name,message:r.message,stack:null===(o=r.stack)||void 0===o?void 0:o.split("\n")},r):t;var r,o}),2)}function oe(e){return h(function(e){for(var n="",t=0,r=Object.keys(e).sort();t<r.length;t++){var o=r[t],a=e[o],i=a.error?"error":JSON.stringify(a.value);n+="".concat(n?"|":"").concat(o.replace(/([:|\\])/g,"\\$1"),":").concat(i)}return n}(e))}function ae(e){return void 0===e&&(e=50),function(e,n){void 0===n&&(n=1/0);var t=window.requestIdleCallback;return t?new Promise((function(e){return t.call(window,(function(){return e()}),{timeout:n})})):o(Math.min(e,n))}(e,2*e)}function ie(e,r){var o=Date.now();return{get:function(a){return n(this,void 0,void 0,(function(){var n,i,c;return t(this,(function(t){switch(t.label){case 0:return n=Date.now(),[4,e()];case 1:return i=t.sent(),c=function(e){var n;return{get visitorId(){return void 0===n&&(n=oe(this.components)),n},set visitorId(e){n=e},confidence:te(e),components:e,version:"3.4.2"}}(i),(r||(null==a?void 0:a.debug))&&console.log("Copy the text below to get the debug data:\n\n```\nversion: ".concat(c.version,"\nuserAgent: ").concat(navigator.userAgent,"\ntimeBetweenLoadAndGet: ").concat(n-o,"\nvisitorId: ").concat(c.visitorId,"\ncomponents: ").concat(re(i),"\n```")),[2,c]}}))}))}}}function ce(e){var r=void 0===e?{}:e,o=r.delayFallback,a=r.debug;return r.monitoring,n(this,void 0,void 0,(function(){return t(this,(function(e){switch(e.label){case 0:return[4,ae(o)];case 1:return e.sent(),[2,ie(V(ne,{debug:a},[]),a)]}}))}))}var ue={load:ce,hashComponents:oe,componentsToDebugString:re},le=h;export{re as componentsToDebugString,ue as default,M as getFullscreenElement,z as getScreenFrame,oe as hashComponents,G as isAndroid,S as isChromium,F as isDesktopSafari,C as isEdgeHTML,Y as isGecko,W as isTrident,x as isWebKit,ce as load,V as loadSources,le as murmurX64Hash128,ae as prepareForSources,ne as sources,Z as transformSource,X as withIframe};
|
upgini/metrics.py
CHANGED
|
@@ -3,15 +3,16 @@ import re
|
|
|
3
3
|
from copy import deepcopy
|
|
4
4
|
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
5
5
|
|
|
6
|
+
import catboost
|
|
6
7
|
import numpy as np
|
|
7
8
|
import pandas as pd
|
|
8
9
|
from catboost import CatBoostClassifier, CatBoostRegressor
|
|
9
|
-
import catboost
|
|
10
10
|
from lightgbm import LGBMClassifier, LGBMRegressor
|
|
11
11
|
from numpy import log1p
|
|
12
12
|
from pandas.api.types import is_numeric_dtype
|
|
13
13
|
from sklearn.metrics import check_scoring, get_scorer, make_scorer, roc_auc_score
|
|
14
14
|
|
|
15
|
+
from upgini.utils.features_validator import FeaturesValidator
|
|
15
16
|
from upgini.utils.sklearn_ext import cross_validate
|
|
16
17
|
|
|
17
18
|
try:
|
|
@@ -352,6 +353,7 @@ class EstimatorWrapper:
|
|
|
352
353
|
"target_type": target_type,
|
|
353
354
|
"groups": groups,
|
|
354
355
|
"text_features": text_features,
|
|
356
|
+
"logger": logger,
|
|
355
357
|
}
|
|
356
358
|
if estimator is None:
|
|
357
359
|
params = dict()
|
|
@@ -414,12 +416,22 @@ class CatBoostWrapper(EstimatorWrapper):
|
|
|
414
416
|
target_type: ModelTaskType,
|
|
415
417
|
groups: Optional[List[str]] = None,
|
|
416
418
|
text_features: Optional[List[str]] = None,
|
|
419
|
+
logger: Optional[logging.Logger] = None,
|
|
417
420
|
):
|
|
418
421
|
super(CatBoostWrapper, self).__init__(
|
|
419
|
-
estimator,
|
|
422
|
+
estimator,
|
|
423
|
+
scorer,
|
|
424
|
+
metric_name,
|
|
425
|
+
multiplier,
|
|
426
|
+
cv,
|
|
427
|
+
target_type,
|
|
428
|
+
groups=groups,
|
|
429
|
+
text_features=text_features,
|
|
430
|
+
logger=logger,
|
|
420
431
|
)
|
|
421
432
|
self.cat_features = None
|
|
422
433
|
self.emb_features = None
|
|
434
|
+
self.exclude_features = []
|
|
423
435
|
|
|
424
436
|
def _prepare_to_fit(self, X: pd.DataFrame, y: pd.Series) -> Tuple[pd.DataFrame, np.ndarray, np.ndarray, dict]:
|
|
425
437
|
X, y, groups, params = super()._prepare_to_fit(X, y)
|
|
@@ -437,9 +449,7 @@ class CatBoostWrapper(EstimatorWrapper):
|
|
|
437
449
|
X, embedding_features = self.group_embeddings(X)
|
|
438
450
|
params["embedding_features"] = embedding_features
|
|
439
451
|
else:
|
|
440
|
-
self.logger.info(
|
|
441
|
-
f"Embedding features count less than 3, so use them separately: {self.emb_features}"
|
|
442
|
-
)
|
|
452
|
+
self.logger.info(f"Embedding features count less than 3, so use them separately: {self.emb_features}")
|
|
443
453
|
self.emb_features = []
|
|
444
454
|
else:
|
|
445
455
|
self.logger.warning(f"Embedding features are not supported by Catboost version {catboost.__version__}")
|
|
@@ -498,6 +508,8 @@ class CatBoostWrapper(EstimatorWrapper):
|
|
|
498
508
|
return df, [emb_name]
|
|
499
509
|
|
|
500
510
|
def _prepare_to_calculate(self, X: pd.DataFrame, y: pd.Series) -> Tuple[pd.DataFrame, np.ndarray, dict]:
|
|
511
|
+
if self.exclude_features:
|
|
512
|
+
X = X.drop(columns=self.exclude_features)
|
|
501
513
|
X, y, params = super()._prepare_to_calculate(X, y)
|
|
502
514
|
if self.text_features:
|
|
503
515
|
params["text_features"] = self.text_features
|
|
@@ -510,6 +522,26 @@ class CatBoostWrapper(EstimatorWrapper):
|
|
|
510
522
|
|
|
511
523
|
return X, y, params
|
|
512
524
|
|
|
525
|
+
def cross_val_predict(
|
|
526
|
+
self, X: pd.DataFrame, y: np.ndarray, baseline_score_column: Optional[Any] = None
|
|
527
|
+
) -> Optional[float]:
|
|
528
|
+
try:
|
|
529
|
+
return super().cross_val_predict(X, y, baseline_score_column)
|
|
530
|
+
except Exception as e:
|
|
531
|
+
if "Dictionary size is 0" in e.args[0] and self.text_features:
|
|
532
|
+
high_cardinality_features = FeaturesValidator.find_high_cardinality(X[self.text_features])
|
|
533
|
+
self.logger.warning(
|
|
534
|
+
"Failed to calculate metrics. Try to remove high cardinality"
|
|
535
|
+
f" text features {high_cardinality_features} and retry"
|
|
536
|
+
)
|
|
537
|
+
for f in high_cardinality_features:
|
|
538
|
+
self.text_features.remove(f)
|
|
539
|
+
self.exclude_features.append(f)
|
|
540
|
+
X = X.drop(columns=f)
|
|
541
|
+
return super().cross_val_predict(X, y, baseline_score_column)
|
|
542
|
+
else:
|
|
543
|
+
raise e
|
|
544
|
+
|
|
513
545
|
|
|
514
546
|
class LightGBMWrapper(EstimatorWrapper):
|
|
515
547
|
def __init__(
|
|
@@ -522,9 +554,18 @@ class LightGBMWrapper(EstimatorWrapper):
|
|
|
522
554
|
target_type: ModelTaskType,
|
|
523
555
|
groups: Optional[List[str]] = None,
|
|
524
556
|
text_features: Optional[List[str]] = None,
|
|
557
|
+
logger: Optional[logging.Logger] = None,
|
|
525
558
|
):
|
|
526
559
|
super(LightGBMWrapper, self).__init__(
|
|
527
|
-
estimator,
|
|
560
|
+
estimator,
|
|
561
|
+
scorer,
|
|
562
|
+
metric_name,
|
|
563
|
+
multiplier,
|
|
564
|
+
cv,
|
|
565
|
+
target_type,
|
|
566
|
+
groups=groups,
|
|
567
|
+
text_features=text_features,
|
|
568
|
+
logger=logger,
|
|
528
569
|
)
|
|
529
570
|
self.cat_features = None
|
|
530
571
|
|
|
@@ -561,9 +602,18 @@ class OtherEstimatorWrapper(EstimatorWrapper):
|
|
|
561
602
|
target_type: ModelTaskType,
|
|
562
603
|
groups: Optional[List[str]] = None,
|
|
563
604
|
text_features: Optional[List[str]] = None,
|
|
605
|
+
logger: Optional[logging.Logger] = None,
|
|
564
606
|
):
|
|
565
607
|
super(OtherEstimatorWrapper, self).__init__(
|
|
566
|
-
estimator,
|
|
608
|
+
estimator,
|
|
609
|
+
scorer,
|
|
610
|
+
metric_name,
|
|
611
|
+
multiplier,
|
|
612
|
+
cv,
|
|
613
|
+
target_type,
|
|
614
|
+
groups=groups,
|
|
615
|
+
text_features=text_features,
|
|
616
|
+
logger=logger,
|
|
567
617
|
)
|
|
568
618
|
self.cat_features = None
|
|
569
619
|
|
|
@@ -595,6 +645,7 @@ class OtherEstimatorWrapper(EstimatorWrapper):
|
|
|
595
645
|
|
|
596
646
|
|
|
597
647
|
def validate_scoring_argument(scoring: Union[Callable, str, None]):
|
|
648
|
+
# TODO validate that if it is Callable then it accepts 3 arguments
|
|
598
649
|
if isinstance(scoring, str) and scoring is not None:
|
|
599
650
|
_get_scorer_by_name(scoring)
|
|
600
651
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
import pandas as pd
|
|
4
|
-
from pandas.api.types import is_float_dtype, is_int64_dtype, is_string_dtype
|
|
4
|
+
from pandas.api.types import is_float_dtype, is_int64_dtype, is_string_dtype, is_object_dtype
|
|
5
5
|
|
|
6
6
|
from upgini.errors import ValidationError
|
|
7
7
|
|
|
@@ -44,7 +44,7 @@ class PhoneNormalizer:
|
|
|
44
44
|
Method will remove all non numeric chars from string and convert it to int.
|
|
45
45
|
None will be set for phone numbers that couldn"t be converted to int
|
|
46
46
|
"""
|
|
47
|
-
if is_string_dtype(self.df[self.phone_column_name]):
|
|
47
|
+
if is_string_dtype(self.df[self.phone_column_name]) or is_object_dtype(self.df[self.phone_column_name]):
|
|
48
48
|
convert_func = self.phone_str_to_int_safe
|
|
49
49
|
elif is_float_dtype(self.df[self.phone_column_name]):
|
|
50
50
|
convert_func = self.phone_float_to_int_safe
|