| """The frozen feature contract. |
| |
| Every column name, every column group, and the exact ordering of the 49 model features |
| live here and nowhere else. Nothing in the codebase may hardcode a column list; it imports |
| one of these constants instead. |
| |
| Why this module is written defensively, with an assertion after every group: the original |
| notebook derived its column groups from whatever DataFrame happened to be in scope. The |
| scaler consequently touched only the 30 numeric columns and left the 19 binaries raw -- |
| not by decision, but because ``numerical_columns`` was a notebook global that closed over |
| the training frame. Every recorded metric depends on that accident. Making the groups |
| explicit and asserting their sizes at import time means a typo fails immediately and |
| loudly, rather than silently changing what the models were fitted on. |
| |
| Dataset column typos are real and preserved verbatim: ``NoOfDegitsInURL``, |
| ``DegitRatioInURL``, ``SpacialCharRatioInURL``. |
| """ |
|
|
| from __future__ import annotations |
|
|
| from typing import Final |
|
|
| |
| |
| |
|
|
| |
| RAW_COLUMNS: Final[tuple[str, ...]] = ( |
| "id", |
| "FILENAME", |
| "URL", |
| "URLLength", |
| "Domain", |
| "DomainLength", |
| "IsDomainIP", |
| "TLD", |
| "CharContinuationRate", |
| "TLDLegitimateProb", |
| "URLCharProb", |
| "TLDLength", |
| "NoOfSubDomain", |
| "HasObfuscation", |
| "NoOfObfuscatedChar", |
| "ObfuscationRatio", |
| "NoOfLettersInURL", |
| "LetterRatioInURL", |
| "NoOfDegitsInURL", |
| "DegitRatioInURL", |
| "NoOfEqualsInURL", |
| "NoOfQMarkInURL", |
| "NoOfAmpersandInURL", |
| "NoOfOtherSpecialCharsInURL", |
| "SpacialCharRatioInURL", |
| "IsHTTPS", |
| "LineOfCode", |
| "LargestLineLength", |
| "HasTitle", |
| "Title", |
| "DomainTitleMatchScore", |
| "URLTitleMatchScore", |
| "HasFavicon", |
| "Robots", |
| "IsResponsive", |
| "NoOfURLRedirect", |
| "NoOfSelfRedirect", |
| "HasDescription", |
| "NoOfPopup", |
| "NoOfiFrame", |
| "HasExternalFormSubmit", |
| "HasSocialNet", |
| "HasSubmitButton", |
| "HasHiddenFields", |
| "HasPasswordField", |
| "Bank", |
| "Pay", |
| "Crypto", |
| "HasCopyrightInfo", |
| "NoOfImage", |
| "NoOfCSS", |
| "NoOfJS", |
| "NoOfSelfRef", |
| "NoOfEmptyRef", |
| "NoOfExternalRef", |
| "label", |
| ) |
|
|
| |
| DROPPED_IDENTIFIER_COLUMNS: Final[tuple[str, ...]] = ("id", "FILENAME") |
| TARGET_COLUMN: Final[str] = "label" |
|
|
| |
| INTERMEDIATE_COLUMNS: Final[tuple[str, ...]] = ("URL", "Domain", "TLD", "Title") |
|
|
| |
| WORKING_COLUMNS: Final[tuple[str, ...]] = tuple( |
| c for c in RAW_COLUMNS if c not in DROPPED_IDENTIFIER_COLUMNS and c != TARGET_COLUMN |
| ) |
|
|
| |
| |
| |
|
|
| |
| |
| |
| FEATURE_ORDER: Final[tuple[str, ...]] = tuple( |
| c for c in WORKING_COLUMNS if c not in INTERMEDIATE_COLUMNS |
| ) |
|
|
| |
| |
| |
|
|
| |
| |
| CATEGORICAL_COLUMNS: Final[tuple[str, ...]] = ( |
| "IsDomainIP", |
| "HasObfuscation", |
| "IsHTTPS", |
| "HasTitle", |
| "HasFavicon", |
| "Robots", |
| "IsResponsive", |
| "HasDescription", |
| "HasSocialNet", |
| "HasSubmitButton", |
| "HasHiddenFields", |
| "HasPasswordField", |
| "Bank", |
| "Pay", |
| "Crypto", |
| "HasCopyrightInfo", |
| "Domain", |
| "URL", |
| "TLD", |
| "Title", |
| "HasExternalFormSubmit", |
| "NoOfSelfRedirect", |
| "NoOfURLRedirect", |
| ) |
|
|
| |
| |
| CATEGORICAL_COLUMNS_FILTERED: Final[tuple[str, ...]] = tuple( |
| c for c in CATEGORICAL_COLUMNS if c not in INTERMEDIATE_COLUMNS |
| ) |
|
|
| |
| |
| |
| |
| CATEGORICAL_COLUMNS_TO_FILL: Final[tuple[str, ...]] = ( |
| "IsDomainIP", |
| "IsHTTPS", |
| "HasTitle", |
| "IsResponsive", |
| "Pay", |
| "HasHiddenFields", |
| "Robots", |
| "Crypto", |
| "HasDescription", |
| "Bank", |
| "HasExternalFormSubmit", |
| "HasFavicon", |
| "HasSubmitButton", |
| "HasPasswordField", |
| "NoOfSelfRedirect", |
| "HasCopyrightInfo", |
| "NoOfURLRedirect", |
| "HasSocialNet", |
| ) |
|
|
| |
| CATEGORICAL_FILL_INITIAL_GROUP_BY: Final[tuple[str, ...]] = ("HasObfuscation",) |
|
|
| |
| |
| NUMERICAL_COLUMNS: Final[tuple[str, ...]] = tuple( |
| c for c in WORKING_COLUMNS if c not in CATEGORICAL_COLUMNS |
| ) |
|
|
| |
| CONTINUOUS_COLUMNS: Final[tuple[str, ...]] = ( |
| "CharContinuationRate", |
| "ObfuscationRatio", |
| "DegitRatioInURL", |
| "DomainTitleMatchScore", |
| "URLTitleMatchScore", |
| "TLDLegitimateProb", |
| "URLCharProb", |
| "LetterRatioInURL", |
| "SpacialCharRatioInURL", |
| ) |
|
|
| |
| DISCRETE_COLUMNS: Final[tuple[str, ...]] = tuple( |
| c for c in NUMERICAL_COLUMNS if c not in CONTINUOUS_COLUMNS |
| ) |
|
|
| |
| |
| |
|
|
| |
| URL_ONLY_FEATURES: Final[tuple[str, ...]] = ( |
| "URLLength", |
| "DomainLength", |
| "IsDomainIP", |
| "CharContinuationRate", |
| "TLDLegitimateProb", |
| "URLCharProb", |
| "TLDLength", |
| "NoOfSubDomain", |
| "HasObfuscation", |
| "NoOfObfuscatedChar", |
| "ObfuscationRatio", |
| "NoOfLettersInURL", |
| "LetterRatioInURL", |
| "NoOfDegitsInURL", |
| "DegitRatioInURL", |
| "NoOfEqualsInURL", |
| "NoOfQMarkInURL", |
| "NoOfAmpersandInURL", |
| "NoOfOtherSpecialCharsInURL", |
| "SpacialCharRatioInURL", |
| "IsHTTPS", |
| ) |
|
|
| |
| |
| TITLE_HYBRID_FEATURES: Final[tuple[str, ...]] = ( |
| "HasTitle", |
| "DomainTitleMatchScore", |
| "URLTitleMatchScore", |
| ) |
|
|
| |
| |
| HTML_FEATURES: Final[tuple[str, ...]] = tuple( |
| c for c in FEATURE_ORDER if c not in URL_ONLY_FEATURES and c not in TITLE_HYBRID_FEATURES |
| ) |
|
|
| |
| |
| |
|
|
| |
| |
| PHISHING_LABEL: Final[int] = 0 |
| LEGITIMATE_LABEL: Final[int] = 1 |
|
|
| |
| |
| MAJORITY_BASELINE_ACCURACY: Final[float] = 0.9248 |
|
|
| |
| PROVENANCE_URL: Final[str] = "url" |
| PROVENANCE_SCRAPED: Final[str] = "scraped" |
| PROVENANCE_IMPUTED: Final[str] = "imputed" |
| PROVENANCE_DEMOTED: Final[str] = "demoted" |
| PROVENANCE_VALUES: Final[frozenset[str]] = frozenset( |
| {PROVENANCE_URL, PROVENANCE_SCRAPED, PROVENANCE_IMPUTED, PROVENANCE_DEMOTED} |
| ) |
|
|
| |
| |
| |
|
|
| assert len(RAW_COLUMNS) == 56, len(RAW_COLUMNS) |
| assert len(set(RAW_COLUMNS)) == 56, "duplicate column name in RAW_COLUMNS" |
| assert len(WORKING_COLUMNS) == 53, len(WORKING_COLUMNS) |
| assert len(FEATURE_ORDER) == 49, len(FEATURE_ORDER) |
|
|
| assert len(CATEGORICAL_COLUMNS) == 23, len(CATEGORICAL_COLUMNS) |
| assert len(CATEGORICAL_COLUMNS_FILTERED) == 19, len(CATEGORICAL_COLUMNS_FILTERED) |
| assert len(CATEGORICAL_COLUMNS_TO_FILL) == 18, len(CATEGORICAL_COLUMNS_TO_FILL) |
| assert len(NUMERICAL_COLUMNS) == 30, len(NUMERICAL_COLUMNS) |
| assert len(CONTINUOUS_COLUMNS) == 9, len(CONTINUOUS_COLUMNS) |
| assert len(DISCRETE_COLUMNS) == 21, len(DISCRETE_COLUMNS) |
|
|
| assert len(URL_ONLY_FEATURES) == 21, len(URL_ONLY_FEATURES) |
| assert len(TITLE_HYBRID_FEATURES) == 3, len(TITLE_HYBRID_FEATURES) |
| assert len(HTML_FEATURES) == 25, len(HTML_FEATURES) |
|
|
| |
| assert set(NUMERICAL_COLUMNS) | set(CATEGORICAL_COLUMNS_FILTERED) == set(FEATURE_ORDER) |
| assert not (set(NUMERICAL_COLUMNS) & set(CATEGORICAL_COLUMNS_FILTERED)) |
|
|
| |
| assert ( |
| set(URL_ONLY_FEATURES) | set(TITLE_HYBRID_FEATURES) | set(HTML_FEATURES) |
| == set(FEATURE_ORDER) |
| ) |
| assert not (set(URL_ONLY_FEATURES) & set(TITLE_HYBRID_FEATURES)) |
| assert not (set(URL_ONLY_FEATURES) & set(HTML_FEATURES)) |
| assert not (set(TITLE_HYBRID_FEATURES) & set(HTML_FEATURES)) |
|
|
| assert set(CONTINUOUS_COLUMNS) <= set(NUMERICAL_COLUMNS) |
| assert set(CATEGORICAL_COLUMNS_TO_FILL) <= set(CATEGORICAL_COLUMNS_FILTERED) |
| assert set(CATEGORICAL_FILL_INITIAL_GROUP_BY) <= set(CATEGORICAL_COLUMNS_FILTERED) |
|
|
| |
| assert set(CATEGORICAL_COLUMNS_FILTERED) - set(CATEGORICAL_COLUMNS_TO_FILL) == set( |
| CATEGORICAL_FILL_INITIAL_GROUP_BY |
| ) |
|
|
| __all__ = [ |
| "CATEGORICAL_COLUMNS", |
| "CATEGORICAL_COLUMNS_FILTERED", |
| "CATEGORICAL_COLUMNS_TO_FILL", |
| "CATEGORICAL_FILL_INITIAL_GROUP_BY", |
| "CONTINUOUS_COLUMNS", |
| "DISCRETE_COLUMNS", |
| "DROPPED_IDENTIFIER_COLUMNS", |
| "FEATURE_ORDER", |
| "HTML_FEATURES", |
| "INTERMEDIATE_COLUMNS", |
| "LEGITIMATE_LABEL", |
| "MAJORITY_BASELINE_ACCURACY", |
| "NUMERICAL_COLUMNS", |
| "PHISHING_LABEL", |
| "PROVENANCE_DEMOTED", |
| "PROVENANCE_IMPUTED", |
| "PROVENANCE_SCRAPED", |
| "PROVENANCE_URL", |
| "PROVENANCE_VALUES", |
| "RAW_COLUMNS", |
| "TARGET_COLUMN", |
| "TITLE_HYBRID_FEATURES", |
| "URL_ONLY_FEATURES", |
| "WORKING_COLUMNS", |
| ] |
|
|