Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
# coding: utf-8
|
2019-08-22 15:21:32 +03:00
|
|
|
from __future__ import unicode_literals
|
|
|
|
|
2019-09-09 20:17:55 +03:00
|
|
|
import srsly
|
|
|
|
from collections import OrderedDict
|
|
|
|
|
|
|
|
from .errors import Errors
|
|
|
|
from .util import SimpleFrozenDict, ensure_path
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
from .strings import hash_string
|
2019-08-22 15:21:32 +03:00
|
|
|
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
from . import util
|
|
|
|
|
|
|
|
import srsly
|
|
|
|
from preshed.bloom import BloomFilter
|
2019-08-22 15:21:32 +03:00
|
|
|
|
|
|
|
class Lookups(object):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""Container for large lookup tables and dictionaries, e.g. lemmatization
|
|
|
|
data or tokenizer exception lists. Lookups are available via vocab.lookups,
|
|
|
|
so they can be accessed before the pipeline components are applied (e.g.
|
|
|
|
in the tokenizer and lemmatizer), as well as within the pipeline components
|
|
|
|
via doc.vocab.lookups.
|
|
|
|
"""
|
|
|
|
|
2019-08-22 15:21:32 +03:00
|
|
|
def __init__(self):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""Initialize the Lookups object.
|
|
|
|
|
|
|
|
RETURNS (Lookups): The newly created object.
|
|
|
|
"""
|
|
|
|
self._tables = OrderedDict()
|
2019-08-22 15:21:32 +03:00
|
|
|
|
|
|
|
def __contains__(self, name):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""Check if the lookups contain a table of a given name. Delegates to
|
|
|
|
Lookups.has_table.
|
|
|
|
|
|
|
|
name (unicode): Name of the table.
|
2019-09-12 15:00:14 +03:00
|
|
|
RETURNS (bool): Whether a table of that name is in the lookups.
|
2019-09-09 20:17:55 +03:00
|
|
|
"""
|
2019-08-22 15:21:32 +03:00
|
|
|
return self.has_table(name)
|
|
|
|
|
2019-09-09 20:17:55 +03:00
|
|
|
def __len__(self):
|
|
|
|
"""RETURNS (int): The number of tables in the lookups."""
|
|
|
|
return len(self._tables)
|
|
|
|
|
2019-08-22 15:21:32 +03:00
|
|
|
@property
|
|
|
|
def tables(self):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""RETURNS (list): Names of all tables in the lookups."""
|
2019-08-22 15:21:32 +03:00
|
|
|
return list(self._tables.keys())
|
|
|
|
|
|
|
|
def add_table(self, name, data=SimpleFrozenDict()):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""Add a new table to the lookups. Raises an error if the table exists.
|
|
|
|
|
|
|
|
name (unicode): Unique name of table.
|
|
|
|
data (dict): Optional data to add to the table.
|
|
|
|
RETURNS (Table): The newly added table.
|
|
|
|
"""
|
2019-08-22 15:21:32 +03:00
|
|
|
if name in self.tables:
|
2019-09-09 20:17:55 +03:00
|
|
|
raise ValueError(Errors.E158.format(name=name))
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
table = Table(name=name, data=data)
|
2019-08-22 15:21:32 +03:00
|
|
|
self._tables[name] = table
|
|
|
|
return table
|
|
|
|
|
|
|
|
def get_table(self, name):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""Get a table. Raises an error if the table doesn't exist.
|
|
|
|
|
|
|
|
name (unicode): Name of the table.
|
|
|
|
RETURNS (Table): The table.
|
|
|
|
"""
|
2019-08-22 15:21:32 +03:00
|
|
|
if name not in self._tables:
|
2019-09-09 20:17:55 +03:00
|
|
|
raise KeyError(Errors.E159.format(name=name, tables=self.tables))
|
2019-08-22 15:21:32 +03:00
|
|
|
return self._tables[name]
|
|
|
|
|
2019-09-09 20:17:55 +03:00
|
|
|
def remove_table(self, name):
|
|
|
|
"""Remove a table. Raises an error if the table doesn't exist.
|
|
|
|
|
2019-09-12 15:00:14 +03:00
|
|
|
name (unicode): Name of the table to remove.
|
2019-09-09 20:17:55 +03:00
|
|
|
RETURNS (Table): The removed table.
|
|
|
|
"""
|
|
|
|
if name not in self._tables:
|
|
|
|
raise KeyError(Errors.E159.format(name=name, tables=self.tables))
|
|
|
|
return self._tables.pop(name)
|
|
|
|
|
2019-08-22 15:21:32 +03:00
|
|
|
def has_table(self, name):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""Check if the lookups contain a table of a given name.
|
|
|
|
|
|
|
|
name (unicode): Name of the table.
|
|
|
|
RETURNS (bool): Whether a table of that name exists.
|
|
|
|
"""
|
2019-08-22 15:21:32 +03:00
|
|
|
return name in self._tables
|
|
|
|
|
2019-09-12 15:00:14 +03:00
|
|
|
def to_bytes(self, **kwargs):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""Serialize the lookups to a bytestring.
|
|
|
|
|
|
|
|
RETURNS (bytes): The serialized Lookups.
|
|
|
|
"""
|
|
|
|
return srsly.msgpack_dumps(self._tables)
|
2019-08-22 15:21:32 +03:00
|
|
|
|
2019-09-12 15:00:14 +03:00
|
|
|
def from_bytes(self, bytes_data, **kwargs):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""Load the lookups from a bytestring.
|
|
|
|
|
2019-09-12 15:00:14 +03:00
|
|
|
bytes_data (bytes): The data to load.
|
|
|
|
RETURNS (Lookups): The loaded Lookups.
|
2019-09-09 20:17:55 +03:00
|
|
|
"""
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
for key, value in srsly.msgpack_loads(bytes_data).items():
|
|
|
|
self._tables[key] = Table(key)
|
|
|
|
self._tables[key].update_raw(value)
|
2019-09-09 20:17:55 +03:00
|
|
|
return self
|
2019-08-22 15:21:32 +03:00
|
|
|
|
2019-09-09 20:17:55 +03:00
|
|
|
def to_disk(self, path, **kwargs):
|
2019-09-12 15:00:14 +03:00
|
|
|
"""Save the lookups to a directory as lookups.bin. Expects a path to a
|
|
|
|
directory, which will be created if it doesn't exist.
|
2019-08-22 15:21:32 +03:00
|
|
|
|
2019-09-09 20:17:55 +03:00
|
|
|
path (unicode / Path): The file path.
|
|
|
|
"""
|
|
|
|
if len(self._tables):
|
|
|
|
path = ensure_path(path)
|
2019-09-12 15:00:01 +03:00
|
|
|
if not path.exists():
|
|
|
|
path.mkdir()
|
2019-09-09 20:17:55 +03:00
|
|
|
filepath = path / "lookups.bin"
|
|
|
|
with filepath.open("wb") as file_:
|
|
|
|
file_.write(self.to_bytes())
|
2019-08-22 15:21:32 +03:00
|
|
|
|
2019-09-09 20:17:55 +03:00
|
|
|
def from_disk(self, path, **kwargs):
|
2019-09-12 15:00:14 +03:00
|
|
|
"""Load lookups from a directory containing a lookups.bin. Will skip
|
|
|
|
loading if the file doesn't exist.
|
2019-09-09 20:17:55 +03:00
|
|
|
|
2019-09-12 15:00:14 +03:00
|
|
|
path (unicode / Path): The directory path.
|
2019-09-09 20:17:55 +03:00
|
|
|
RETURNS (Lookups): The loaded lookups.
|
|
|
|
"""
|
|
|
|
path = ensure_path(path)
|
|
|
|
filepath = path / "lookups.bin"
|
|
|
|
if filepath.exists():
|
|
|
|
with filepath.open("rb") as file_:
|
|
|
|
data = file_.read()
|
|
|
|
return self.from_bytes(data)
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
|
|
class Table(OrderedDict):
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
"""A table in the lookups. Subclass of builtin dict that implements a
|
|
|
|
slightly more consistent and unified API.
|
|
|
|
|
|
|
|
Includes a Bloom filter to speed up missed lookups.
|
2019-09-09 20:17:55 +03:00
|
|
|
"""
|
2019-09-11 15:00:36 +03:00
|
|
|
|
2019-09-09 20:17:55 +03:00
|
|
|
@classmethod
|
|
|
|
def from_dict(cls, data, name=None):
|
2019-09-12 15:00:14 +03:00
|
|
|
"""Initialize a new table from a dict.
|
|
|
|
|
|
|
|
data (dict): The dictionary.
|
|
|
|
name (unicode): Optional table name for reference.
|
|
|
|
RETURNS (Table): The newly created object.
|
|
|
|
"""
|
2019-09-09 20:17:55 +03:00
|
|
|
self = cls(name=name)
|
|
|
|
self.update(data)
|
|
|
|
return self
|
2019-08-22 15:21:32 +03:00
|
|
|
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
def __init__(self, name=None, data=None):
|
2019-09-09 20:17:55 +03:00
|
|
|
"""Initialize a new table.
|
|
|
|
|
|
|
|
name (unicode): Optional table name for reference.
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
data (dict): Initial data, used to hint Bloom Filter.
|
2019-09-09 20:17:55 +03:00
|
|
|
RETURNS (Table): The newly created object.
|
|
|
|
"""
|
|
|
|
OrderedDict.__init__(self)
|
2019-08-22 15:21:32 +03:00
|
|
|
self.name = name
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
# assume a default size of 1M items
|
|
|
|
size = 1E6
|
|
|
|
if data and len(data) > 0:
|
|
|
|
size = len(data)
|
|
|
|
|
|
|
|
self.bloom = BloomFilter.from_error_rate(size)
|
2019-08-22 15:21:32 +03:00
|
|
|
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
if data:
|
|
|
|
self.update(data)
|
|
|
|
|
|
|
|
def set(self, key, value):
|
|
|
|
"""Set new key/value pair, where key is an integer. Same as
|
|
|
|
table[key] = value.
|
|
|
|
"""
|
2019-08-22 15:21:32 +03:00
|
|
|
self[key] = value
|
Bloom-filter backed Lookup Tables (#4268)
* Improve load_language_data helper
* WIP: Add Lookups implementation
* Start moving lemma data over to JSON
* WIP: move data over for more languages
* Convert more languages
* Fix lemmatizer fixtures in tests
* Finish conversion
* Auto-format JSON files
* Fix test for now
* Make sure tables are stored on instance
* Update docstrings
* Update docstrings and errors
* Update test
* Add Lookups.__len__
* Add serialization methods
* Add Lookups.remove_table
* Use msgpack for serialization to disk
* Fix file exists check
* Try using OrderedDict for everything
* Update .flake8 [ci skip]
* Try fixing serialization
* Update test_lookups.py
* Update test_serialize_vocab_strings.py
* Lookups / Tables now work
This implements the stubs in the Lookups/Table classes. Currently this
is in Cython but with no type declarations, so that could be improved.
* Add lookups to setup.py
* Actually add lookups pyx
The previous commit added the old py file...
* Lookups work-in-progress
* Move from pyx back to py
* Add string based lookups, fix serialization
* Update tests, language/lemmatizer to work with string lookups
There are some outstanding issues here:
- a pickling-related test fails due to the bloom filter
- some custom lemmatizers (fr/nl at least) have issues
More generally, there's a question of how to deal with the case where
you have a string but want to use the lookup table. Currently the table
allows access by string or id, but that's getting pretty awkward.
* Change lemmatizer lookup method to pass (orth, string)
* Fix token lookup
* Fix French lookup
* Fix lt lemmatizer test
* Fix Dutch lemmatizer
* Fix lemmatizer lookup test
This was using a normal dict instead of a Table, so checks for the
string instead of an integer key failed.
* Make uk/nl/ru lemmatizer lookup methods consistent
The mentioned tokenizers all have their own implementation of the
`lookup` method, which accesses a `Lookups` table. The way that was
called in `token.pyx` was changed so this should be updated to have the
same arguments as `lookup` in `lemmatizer.py` (specificially (orth/id,
string)).
Prior to this change tests weren't failing, but there would probably be
issues with normal use of a model. More tests should proably be added.
Additionally, the language-specific `lookup` implementations seem like
they might not be needed, since they handle things like lower-casing
that aren't actually language specific.
* Make recently added Greek method compatible
* Remove redundant class/method
Leftovers from a merge not cleaned up adequately.
2019-09-12 18:26:11 +03:00
|
|
|
|
|
|
|
def __setitem__(self, key, value):
|
|
|
|
OrderedDict.__setitem__(self, key, value)
|
|
|
|
self.bloom.add(key)
|
|
|
|
|
|
|
|
def set_string(self, key, value):
|
|
|
|
"""Set new key/value pair, where key is a string to be hashed.
|
|
|
|
"""
|
|
|
|
hkey = hash_string(key)
|
|
|
|
self.set(hkey, value)
|
|
|
|
|
|
|
|
def update(self, data):
|
|
|
|
"""Add entries in a dict-like to the table, where keys are strings to
|
|
|
|
be hashed.
|
|
|
|
"""
|
|
|
|
for key, val in data.items():
|
|
|
|
self.set_string(key, val)
|
|
|
|
|
|
|
|
def update_raw(self, data):
|
|
|
|
"""Add entries in a dict-like to the table, where keys are ints.
|
|
|
|
"""
|
|
|
|
for key, val in data.items():
|
|
|
|
self.set(key, val)
|
|
|
|
|
|
|
|
def get(self, key, default=None):
|
|
|
|
return OrderedDict.get(self, key, default)
|
|
|
|
|
|
|
|
def get_string(self, key, default=None):
|
|
|
|
hkey = hash_string(key)
|
|
|
|
return OrderedDict.get(self, hkey, default)
|
|
|
|
|
|
|
|
def __contains__(self, key):
|
|
|
|
# This can give a false positive, so we need to check it after
|
|
|
|
if key not in self.bloom:
|
|
|
|
return False
|
|
|
|
return OrderedDict.__contains__(self, key)
|
|
|
|
|
|
|
|
def contains_string(self, key):
|
|
|
|
hkey = hash_string(key)
|
|
|
|
return self.__contains__(hkey)
|
|
|
|
|
|
|
|
def to_bytes(self):
|
|
|
|
# TODO: serialize bloom too. For now just reconstruct it.
|
|
|
|
return srsly.msgpack_dumps({'name': self.name, 'dict': dict(self.items())})
|
|
|
|
|
|
|
|
def from_bytes(self, data):
|
|
|
|
loaded = srsly.msgpack_loads(data)
|
|
|
|
self.name = loaded['name']
|
|
|
|
for key, val in loaded['dict'].items():
|
|
|
|
self[key] = val
|
|
|
|
self.bloom.add(key)
|
|
|
|
|
|
|
|
return self
|
|
|
|
|