Skip to content

Commit

Permalink
use rules to reduce model size: DE, EN, FI, NL
Browse files Browse the repository at this point in the history
  • Loading branch information
adbar committed Jan 12, 2023
1 parent 6aa9ffe commit fd93714
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 135 deletions.
Binary file modified simplemma/data/de.plzma
Binary file not shown.
Binary file modified simplemma/data/en.plzma
Binary file not shown.
Binary file modified simplemma/data/fi.plzma
Binary file not shown.
Binary file modified simplemma/data/nl.plzma
Binary file not shown.
260 changes: 139 additions & 121 deletions simplemma/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,130 +192,148 @@ def apply_nl(token: str) -> Optional[str]:
return None


FINNISH_ENDINGS = {
# -minen nouns, ä/ö/y + a/o/u
# https://en.wiktionary.org/wiki/-minen
"miset": "minen",
"misen": "minen",
"misten": "minen",
"miseen": "minen",
"misia": "minen",
"misiä": "minen",
"misiin": "minen",
"misin": "minen",
# -inen nouns
"isissa": "inen", # liikenaisissa → liikenainen
"isissä": "inen",
"isista": "inen", # liikenaisista → liikenainen
"isistä": "inen",
"iseksi": "inen", # liikenaiseksi → liikenainen
"iseen": "inen", # liikenaiseen → liikenainen
"isella": "inen", # liikenaisella → liikenainen
"isellä": "inen",
"iselle": "inen", # liikenaiselle → liikenainen
"iselta": "inen", # liikenaiselta → liikenainen
"iseltä": "inen",
"iseni": "inen", # liikenaiseni → liikenainen
"isensa": "inen", # liikenaisensa → liikenainen
"isensä": "inen",
"isesi": "inen", # liikenaisesi → liikenainen
"isessa": "inen", # liikenaisessa → liikenainen
"isessä": "inen",
"isesta": "inen", # liikenaisesta → liikenainen
"isestä": "inen",
"isien": "inen", # liikenaisien → liikenainen
"isiksi": "inen", # liikenaisiksi → liikenainen
"isilla": "inen", # liikenaisilla → liikenainen
"isillä": "inen",
"isilta": "inen", # liikenaisilta → liikenainen
"isiltä": "inen",
"isille": "inen", # liikenaisille → liikenainen
"isina": "inen", # liikenaisina → liikenainen
"isinä": "inen",
"isineen": "inen", # liikenaisineen → liikenainen
"isitta": "inen", # liikenaisitta → liikenainen
"isittä": "inen",
"isemme": "inen", # liikenaisemme → liikenainen
"isenne": "inen", # liikenaisenne → liikenainen
"isille": "inen", # liikenaisille → liikenainen
"iselta": "inen", # liikenaiselta → liikenainen
"iseltä": "inen",
"isetta": "inen", # liikenaisetta → liikenainen
"isettä": "inen",
# -ainen for more precision
"aisen": "ainen", # liikenaisen → liikenainen
"aiset": "ainen", # liikenaiset → liikenainen
"aisia": "ainen", # liikenaisia → liikenainen
# -uus nouns: https://en.wiktionary.org/wiki/nerokkuus
"uudet": "uus",
"uuden": "uus",
"uuksien": "uus",
"uuksiin": "uus",
"uuksia": "uus",
"uudessa": "uus",
"uuksissa": "uus",
"uuteen": "uus",
"uudella": "uus",
"uuksilla": "uus",
"uudelta": "uus",
"uuksilta": "uus",
"uudelle": "uus",
"uuksille": "uus",
"uutena": "uus",
"uuksina": "uus",
"uudeksi": "uus",
"uuksiksi": "uus",
"uuksin": "uus",
"uudetta": "uus",
"uuksitta": "uus",
"uuksineen": "uus",
"uuteni": "uus",
"uutemme": "uus",
"uutesi": "uus",
"uutenne": "uus",
"uutensa": "uus",
# -tti: https://en.wiktionary.org/wiki/luotti
"ttien": "tti",
"ttia": "tti",
"ttiä": "tti",
"tteja": "tti",
"ttejä": "tti",
"tissä": "tti",
"tiltä": "tti",
"ttina": "tti",
"ttinä": "tti",
"tteinä": "tti",
"tittä": "tti",
"ttini": "tti",
"ttimme": "tti",
"ttisi": "tti",
"ttinne": "tti",
"ttinsa": "tti",
"ttinsä": "tti",
# too much noise
# "mista": "minen",
# "mistä": "minen",
# "isten": "inen", # liikenaisten → liikenainen
# "aisin": "ainen", # liikenaisin → liikenainen
# "aista": "ainen", # liikenaista → liikenainen
# "uutta": "uus",
# "ttiin": "tti",
# "teille": "tti",
# "teiksi": "tti",
# "teista": "tti",
# "teilla": "tti",
# "teilta": "tti",
# "teillä": "tti",
# "teiltä": "tti",
# "teitta": "tti",
# "teittä": "tti",
# "teissa": "tti",
# "teissä": "tti",
# "tille": "tti",
# "tiksi": "tti",
# "tissa": "tti",
# "titta": "tti",
# "tilta": "tti",
# "teistä": "tti",
# "tteineen": "tti",
# "tteihin": "tti",
# "tteina": "tti",
}


def apply_fi(token: str) -> Optional[str]:
"Apply pre-defined rules for Finnish."
if len(token) < 10:
if len(token) < 10 or token[0].isupper():
return None
## -inen nouns
# liikenaisen → liikenainen
if token.endswith("isen"):
return token[:-3] + "nen"
# liikenaiset → liikenainen
if token.endswith("iset"):
return token[:-3] + "nen"
# liikenaisia → liikenainen
if token.endswith("isia"):
return token[:-3] + "nen"
# liikenaisissa → liikenainen
if token.endswith("isissa"):
return token[:-5] + "nen"
# liikenaisista → liikenainen
if token.endswith("isista"):
return token[:-5] + "nen"
# liikenaiseksi → liikenainen
if token.endswith("iseksi"):
return token[:-5] + "nen"
# liikenaiseen → liikenainen
if token.endswith("iseen"):
return token[:-4] + "nen"
# liikenaisella → liikenainen
if token.endswith("isella"):
return token[:-5] + "nen"
# liikenaiselle → liikenainen
if token.endswith("iselle"):
return token[:-5] + "nen"
# liikenaiselta → liikenainen
if token.endswith("iselta"):
return token[:-5] + "nen"
# liikenaiseni → liikenainen
if token.endswith("iseni"):
return token[:-4] + "nen"
# liikenaisensa → liikenainen
if token.endswith("isensa"):
return token[:-5] + "nen"
# liikenaisesi → liikenainen
if token.endswith("isesi"):
return token[:-4] + "nen"
# liikenaisessa → liikenainen
if token.endswith("isessa"):
return token[:-5] + "nen"
# liikenaisesta → liikenainen
if token.endswith("isesta"):
return token[:-5] + "nen"
# liikenaisien → liikenainen
if token.endswith("isien"):
return token[:-4] + "nen"
# liikenaisiksi → liikenainen
if token.endswith("isiksi"):
return token[:-5] + "nen"
# liikenaisilla → liikenainen
if token.endswith("isilla"):
return token[:-5] + "nen"
# liikenaisilta → liikenainen
if token.endswith("isilta"):
return token[:-5] + "nen"
# liikenaisille → liikenainen
if token.endswith("isille"):
return token[:-5] + "nen"
# liikenaisin → liikenainen
if token.endswith("isin"):
return token[:-3] + "nen"
# liikenaisina → liikenainen
if token.endswith("isina"):
return token[:-4] + "nen"
# liikenaisineen → liikenainen
if token.endswith("isineen"):
return token[:-6] + "nen"
# liikenaisitta → liikenainen
if token.endswith("isitta"):
return token[:-5] + "nen"
# liikenaisten → liikenainen
if token.endswith("isten"):
return token[:-4] + "nen"
# liikenaisemme → liikenainen
if token.endswith("isemme"):
return token[:-5] + "nen"
# liikenaisenne → liikenainen
if token.endswith("isenne"):
return token[:-5] + "nen"
# liikenaisille → liikenainen
if token.endswith("isille"):
return token[:-5] + "nen"
# liikenaiselta → liikenainen
if token.endswith("iselta"):
return token[:-5] + "nen"
# liikenaisetta → liikenainen
if token.endswith("isetta"):
return token[:-5] + "nen"
# liikenaisten → liikenainen
if token.endswith("isten"):
return token[:-4] + "nen"
## others
if token.endswith("tteja"):
return token[:-3] + "i"
## too much noise
# liikenaista → liikenainen
# if token.endswith("ista"):
# return token[:-3] + "nen"
# if token.endswith("isiin"):
# return token[:-4] + "nen"
# if token.endswith("ain"):
# return token[:-2]
# if token.endswith("ini"):
# return token[:-2]
# if token.endswith("inne"):
# return token[:-3]
# if token.endswith("insa"):
# return token[:-3]
# if token.endswith("ässä"):
# return token[:-3]
# if token.endswith("olla"):
# return token[:-3]
# if token.endswith("ossa"):
# return token[:-3]
# if token.endswith("eja"):
# return token[:-3] + "i"
## too rare
for ending, base in FINNISH_ENDINGS.items():
if token.endswith(ending):
return token[: -len(ending)] + base
## others: but not yritteineen/yrite
# if token.endswith("eineen") and token[-7] != token[-8]:
# return token[:-6] + "i"
## too rare?
# äyskäisen → äyskäistä
# if token.endswith("äisen"):
# return token[:-4]
Expand Down
17 changes: 12 additions & 5 deletions simplemma/simplemma.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Main module."""


import lzma
import logging
import pickle
Expand All @@ -15,7 +14,8 @@
from .tokenizer import simple_tokenizer
# local error, also ModuleNotFoundError for Python >= 3.6
except ImportError: # pragma: no cover
pass
from rules import apply_rules, RULES_LANGS # type: ignore
from tokenizer import simple_tokenizer # type: ignore


LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -97,7 +97,7 @@
"tr",
}
BETTER_LOWER = {"bg", "es", "hy", "lt", "lv", "pt", "sk"}
BUFFER_HACK = {"bg", "es", "et", "fi", "fr", "it", "lt", "pl", "sk"} # "da"
BUFFER_HACK = {"bg", "es", "et", "fi", "fr", "it", "lt", "pl", "sk"} # "da", "nl"
LONGER_AFFIXES = {"et", "fi", "hu", "lt"}
SHORTER_GREEDY = {"bg", "et", "fi"}

Expand Down Expand Up @@ -164,10 +164,17 @@ def _read_dict(filepath: str, langcode: str, silent: bool) -> Dict[str, str]:
):
continue
# length difference
if len(columns[0]) == 1 and len(columns[1]) > 5:
if len(columns[0]) == 1 and len(columns[1]) > 6:
continue
if len(columns[0]) > 5 and len(columns[1]) == 1:
if len(columns[0]) > 6 and len(columns[1]) == 1:
continue
# tackled by rules
if len(columns[1]) > 6: # columns[1] != columns[0]
rule = apply_rules(columns[1], langcode)
if rule == columns[0]:
continue
elif rule is not None and rule != columns[1]:
print(columns[1], columns[0], apply_rules(columns[1], langcode))
# process
if columns[1] in mydict and mydict[columns[1]] != columns[0]:
# prevent mistakes and noise coming from the lists
Expand Down
3 changes: 1 addition & 2 deletions tests/test_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,9 @@ def test_apply_fi():
assert apply_fi("liikenaisilla") == "liikenainen"
assert apply_fi("liikenaisilta") == "liikenainen"
assert apply_fi("liikenaisille") == "liikenainen"
assert apply_fi("liikenaisin") == "liikenainen"
assert apply_fi("liikenaisina") == "liikenainen"
assert apply_fi("liikenaisineen") == "liikenainen"
assert apply_fi("liikenaisitta") == "liikenainen"
assert apply_fi("liikenaisten") == "liikenainen"
assert apply_fi("liikenaisemme") == "liikenainen"
assert apply_fi("liikenaisenne") == "liikenainen"
assert apply_fi("liikenaisille") == "liikenainen"
Expand All @@ -161,3 +159,4 @@ def test_apply_rules():
assert apply_rules("atonements", "de") is None
assert apply_rules("atonements", "en") == "atonement"
assert apply_rules("brieven", "nl") == "brief"
assert apply_rules("liikenaisessa", "fi") == "liikenainen"
11 changes: 4 additions & 7 deletions tests/test_simplemma.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,7 @@ def test_subwords():
== "insulinproduzierend"
)
assert lemmatize("Urlaubsreisenden", lang="de", greedy=True) == "Urlaubsreisende"
assert (
lemmatize("Grünenvorsitzende", lang="de", greedy=True) == "Grünenvorsitzende"
)
assert lemmatize("Grünenvorsitzende", lang="de", greedy=True) == "Grünenvorsitzende"
assert (
lemmatize("Qualifikationsrunde", lang="de", greedy=True)
== "Qualifikationsrunde"
Expand All @@ -319,17 +317,17 @@ def test_subwords():
assert (
lemmatize("Gen-Sequenzierungen", lang="de", greedy=True) == "Gen-Sequenzierung"
)
# assert lemmatize("wiederverwendbaren", lang="de", greedy=True) == "wiederverwendbar"
assert lemmatize("wiederverwendbaren", lang="de", greedy=True) == "wiederverwendbar"
assert lemmatize("Spitzenposten", lang="de", greedy=True) == "Spitzenposten"
assert lemmatize("I-Pace", lang="de", greedy=True) == "I-Pace"
assert (
lemmatize("PCR-Bestätigungstests", lang="de", greedy=True)
== "PCR-Bestätigungstest"
)
#assert (
# assert (
# lemmatize("standortübergreifend", lang="de", greedy=True)
# == "standortübergreifend"
#)
# )
assert lemmatize("obamamäßigsten", lang="de", greedy=True) == "obamamäßig"
assert lemmatize("obamaartigere", lang="de", greedy=True) == "obamaartig"
assert lemmatize("durchgestyltes", lang="de", greedy=True) == "durchgestylt"
Expand Down Expand Up @@ -358,7 +356,6 @@ def test_subwords():
# assert lemmatize("Bandmitgliedern", lang="de", greedy=True) == "Bandmitglied"



def test_tokenizer():
# tokenization and chaining
text = "Sent1. Sent2\r\nSent3"
Expand Down

0 comments on commit fd93714

Please sign in to comment.