Class TextQualityFeatures
wild-roaming-whale). All features are pure functions of a
decoded String so they can be computed by the eval harness without
touching the trained bigram model. Intended to migrate into
JunkDetector's feature vector after the study identifies the
non-redundant subset.
Also hosts the TextQualityFeatures.StripMode enum and strip(String, TextQualityFeatures.StripMode) entry point.
The current production behaviour
(JunkFilterEncodingDetector.stripCommonCodepoints) corresponds to
TextQualityFeatures.StripMode.ALL_COMMON — it strips every COMMON / INHERITED /
UNKNOWN codepoint before scoring. The user observation in the plan was
that this is too aggressive: it removes pilcrows and other punctuation
marks that are themselves mojibake fingerprints. The other modes let the
eval measure that empirically.
-
Nested Class Summary
Nested Classes -
Method Summary
Modifier and TypeMethodDescriptionstatic doublealphabeticRatio(String text) z6: fraction of codepoints that are letters (Character.isLetter(int)).static doublecombiningMarkRatio(String text) z10: fraction of codepoints that are combining or spacing marks (Unicode general categories Mn, Mc, Me).static doublehighByteEntropy(String text) z7: Shannon entropy (in bits) of the distribution of distinct codepoints in the high-byte range (cp >= 0x80).static doublez11: fraction of adjacent codepoint pairs where the first is a letter and the second is a combining or spacing mark.static doubleletterPairDensity(String text) z5: fraction of adjacent codepoint pairs where both codepoints are letters in the same script cluster.static doubleperWordScriptPurity(String text) Candidate feature (not currently in the classifier): fraction of whitespace-delimited tokens whose letter codepoints all belong to the same script cluster.static intreplacementCount(String text) Raw count of U+FFFD codepoints.static doublereplacementRatio(String text) z6 raw input: fraction of codepoints that are "anomaly indicators" — codepoints that shouldn't appear in correctly-decoded natural text.static doublescriptAlternationRatio(String text) z9: script-alternation ratio — observed transitions over expected transitions under a random-shuffle null.static doublescriptDensity(String text) Fraction of codepoints assigned to a "real" script (i.e. not in COMMON / INHERITED / UNKNOWN).static doublescriptFragmentation(String text) Fragmentation of script-bearing codepoints across distinct scripts:1 - longest_same_script_run_length / total_script_codepoints.static Stringstrip(String text, TextQualityFeatures.StripMode mode)
-
Method Details
-
strip
-
alphabeticRatio
z6: fraction of codepoints that are letters (Character.isLetter(int)). Polishciśnienia≈ 1.0;ci¶nienia< 1.0 because¶is not a letter. -
letterPairDensity
z5: fraction of adjacent codepoint pairs where both codepoints are letters in the same script cluster. Script cluster groups HAN + HIRAGANA + KATAKANA + HANGUL + BOPOMOFO (CJK) into one cluster so Japanese mixed text and Korean Hanja text count as same-cluster pairs; all other scripts are their own cluster.Polish
ciśnienia→ 1.0 (every adjacent pair is two LATIN letters).ci¶nienia→ 0.75 (the two pairs involving¶fail the both-letters test). -
highByteEntropy
z7: Shannon entropy (in bits) of the distribution of distinct codepoints in the high-byte range (cp >= 0x80). Clean text uses a small alphabet there; CJK-as-Latin mojibake (theƅstorm) fans out across many distinct codepoints, raising entropy. Returns 0 if no high-byte codepoints are present. -
replacementRatio
z6 raw input: fraction of codepoints that are "anomaly indicators" — codepoints that shouldn't appear in correctly-decoded natural text. Direct decode-failure signal — wrong encodings produce these in bulk (Java's CharsetDecoder emits U+FFFD per malformed byte; ISO-8859-X misreads windows-1252 high bytes as C1 controls; PDF cmap failures emit private-use codepoints; etc.).Anomaly set:
- U+FFFD (REPLACEMENT CHARACTER) — the direct decode-failure marker
- Anomalous Cc:
0x01-0x08, 0x0B, 0x0C, 0x0E-0x1F, 0x7F(matching z3's byte-level anomaly definition, at codepoint level) - C1 control codepoints:
U+0080-U+009F— the ISO-8859-X-misdecodes-windows-1252 signal - Private use area:
U+E000-U+F8FF, plus planes 15-16 PUA — the PDF cmap-failure signal
Continuous (not a binary threshold) so the JunkDetector combiner LR can learn a proportional weight on it. Excluded: 0x00 (NUL — can occur legitimately in some text streams; matches z3's exclusion); 0x09/0x0A/0x0D/0x20 (legitimate whitespace); Cf format chars (ZWJ etc. have legitimate linguistic uses); Cn unassigned (rare in practice).
-
replacementCount
Raw count of U+FFFD codepoints. Kept for diagnostics — the per-record eval TSV emits both the count (for easy spot-checking of "how bad was this decode") and the ratio (the trainable feature). -
combiningMarkRatio
z10: fraction of codepoints that are combining or spacing marks (Unicode general categories Mn, Mc, Me). Real Vietnamese / Indic / Thai / Arabic text uses combining marks heavily (Vietnamese ~30 %); mojibake from re-decoding precomposed scripts as Latin-1 has zero. Companion / corrective signal toalphabeticRatio(String), which is backwards on Vietnamese cohorts because marks aren't letters. Works on a single 5-codepoint word. -
letterAdjacentToMarkRatio
z11: fraction of adjacent codepoint pairs where the first is a letter and the second is a combining or spacing mark. Bigram-shaped companion tocombiningMarkRatio(String)— direct positive signal for "letter wearing decoration," which is what correct Vietnamese / Indic / Thai decoding produces and Latin-1 mojibake of those does not. -
scriptDensity
Fraction of codepoints assigned to a "real" script (i.e. not in COMMON / INHERITED / UNKNOWN). Pure-whitespace, pure-digit, and pure-punctuation text score 0; mostly-letter text scores near 1.Used by JunkDetector's "no scoreable script" fallback classifier (the "NONE" model) to distinguish "real text in an unmodeled script" (high density, low fragmentation → modestly positive signal) from "all-whitespace / digit-only content" (zero density → strong negative signal in JunkDetector's bigram-based judgment, mild signal for general-purpose junk filtering).
U+FFFD is excluded from both numerator and denominator: it is a decode-failure marker scored by the dedicated replacement-char feature (z6), so counting it here too would (a) double- count FFFD and (b) re-create the FFFD-drag when this feature dominates — a permissive wrong decode (few FFFD) would out-score a correct mixed- encoding decode (many FFFD from undecodable widget bytes). This measures the composition of the *decodable* content only.
-
scriptFragmentation
Fragmentation of script-bearing codepoints across distinct scripts:1 - longest_same_script_run_length / total_script_codepoints. Coherent one-script text scores 0 (no fragmentation); script-salad mojibake (many tiny runs across multiple scripts) approaches 1.Combined with
scriptDensity(String), distinguishes the four "no-scoreable-script" failure modes:- All-whitespace / pure-digit: density 0, fragmentation 0 (no scripted codepoints at all).
- Real Gothic / unmodeled-but-coherent script: density 1, fragmentation 0 (one long run).
- Script-salad mojibake: density > 0.5, fragmentation > 0.7 (many short runs across many scripts).
- Real multilingual text (e.g. Japanese with romaji): density 1, fragmentation 0.3-0.5 (a handful of long runs).
Returns 0 when text has no script-bearing codepoints (so the caller can rely on
scriptDensity(String)to discriminate the "no-content" case separately). -
scriptAlternationRatio
z9: script-alternation ratio — observed transitions over expected transitions under a random-shuffle null.Formally: for a sequence of n non-COMMON codepoints with script proportions
p_1, ..., p_k, the expected number of (transition between different scripts) under random shuffling is(n - 1) * (1 - sum(p_i^2))— the second factor is Gini-Simpson diversity (probability two random positions differ in script). This is the Wald-Wolfowitz runs-test statistic generalised to k categories.Returns
observed_transitions / expected_transitions:- ≈ 1 — scripts randomly interleaved (the mojibake signature when accents are scattered through Latin text — each accent becomes a singleton Han run, looking random)
- < 1 — clumped (normal: words/phrases stay in one script; English document with embedded Chinese phrase scores 0.05-0.3)
- > 1 — more alternating than chance (pathological: "HLHLHL" patterns)
Length- and proportion-invariant by construction. COMMON / INHERITED / UNKNOWN codepoints are ignored to keep whitespace and punctuation from dominating the signal in normal text.
Returns 0 for single-script documents (no diversity possible).
-
perWordScriptPurity
Candidate feature (not currently in the classifier): fraction of whitespace-delimited tokens whose letter codepoints all belong to the same script cluster. Mojibake often produces tokens with mixed-script letters (Latin + Cyrillic + Greek in one "word"). Tokens with zero letters are excluded from both numerator and denominator.
-