medcat.utils.data_utils ======================= .. py:module:: medcat.utils.data_utils Classes ------- .. autoapisummary:: medcat.utils.data_utils.CDB medcat.utils.data_utils.MedCATTrainerExport medcat.utils.data_utils.MedCATTrainerExportProject medcat.utils.data_utils.MedCATTrainerExportDocument medcat.utils.data_utils.MutableDocument medcat.utils.data_utils.MutableEntity medcat.utils.data_utils.TestTrainSplitter Functions --------- .. autoapisummary:: medcat.utils.data_utils.make_mc_train_test medcat.utils.data_utils.get_false_positives Module Contents --------------- .. py:class:: CDB(config) Bases: :py:obj:`medcat.storage.serialisables.AbstractSerialisable` The abstract serialisable base class. This defines some common defaults. .. py:method:: __init__(config) .. py:attribute:: config .. py:attribute:: cui2info :type: dict[str, medcat.cdb.concepts.CUIInfo] .. py:attribute:: name2info :type: dict[str, medcat.cdb.concepts.NameInfo] .. py:attribute:: type_id2info :type: dict[str, medcat.cdb.concepts.TypeInfo] .. py:attribute:: token_counts :type: dict[str, int] .. py:attribute:: addl_info :type: dict[str, Any] .. py:attribute:: _subnames :type: set[str] .. py:attribute:: is_dirty :value: False .. py:attribute:: has_changed_names :value: False .. py:method:: get_init_attrs() :classmethod: .. py:method:: _reset_subnames() .. py:method:: has_subname(name) Whether the CDB has the specified subname. :param name: The subname to check. :type name: str :Returns: **bool** -- Whether the subname is present in this CDB. .. py:method:: get_name(cui) Returns preferred name if it exists, otherwise it will return the longest name assigned to the concept. :param cui: Concept ID or unique identifier in this database. :type cui: str :Returns: **str** -- The name of the concept. .. py:method:: weighted_average_function(step) Get the weighted average for steop. :param step: The steop. :type step: int :Returns: **float** -- The weighted average. .. py:method:: add_types(types) Add type info to CDB. :param types: The raw type info. :type types: Iterable[tuple[str, str]] .. py:method:: add_names(cui, names, name_status = ST.AUTOMATIC, full_build = False) Adds a name to an existing concept. :param cui: Concept ID or unique identifier in this database, all concepts that have the same CUI will be merged internally. :type cui: str :param names: Names for this concept, or the value that if found in free text can be linked to this concept. Names is an dict like: `{name: {'tokens': tokens, 'snames': snames, 'raw_name': raw_name}, ...}` Names should be generated by helper function 'medcat.preprocessing.cleaners.prepare_name' :type names: dict[str, NameDescriptor] :param name_status: One of `P`, `N`, `A`. Defaults to 'A'. :type name_status: str :param full_build: If True the dictionary self.addl_info will also be populated, contains a lot of extra information about concepts, but can be very memory consuming. This is not necessary for normal functioning of MedCAT (Default value `False`). :type full_build: bool .. py:method:: _add_concept_names(cui, names, name_status) .. py:method:: _add_full_build(cui, names, ontologies, description, type_ids) .. py:method:: _add_concept(cui, names, ontologies, name_status, type_ids, description, full_build = False) Add a concept to internal Concept Database (CDB). Depending on what you are providing this will add a large number of properties for each concept. :param cui: Concept ID or unique identifier in this database, all concepts that have the same CUI will be merged internally. :type cui: str :param names: Names for this concept, or the value that if found in free text can be linked to this concept. Names is a dict like: `{name: {'tokens': tokens, 'snames': snames, 'raw_name': raw_name}, ...}` Names should be generated by helper function 'medcat.preprocessing.cleaners.prepare_name' :type names: dict[str, NameDescriptor] :param ontologies: ontologies in which the concept exists (e.g. SNOMEDCT, HPO) :type ontologies: set[str] :param name_status: One of `P`, `N`, `A` :type name_status: str :param type_ids: Semantic type identifier (have a look at TUIs in UMLS or SNOMED-CT) :type type_ids: set[str] :param description: Description of this concept. :type description: str :param full_build: If True the dictionary self.addl_info will also be populated, contains a lot of extra information about concepts, but can be very memory consuming. This is not necessary for normal functioning of MedCAT (Default Value `False`). :type full_build: bool .. py:method:: reset_training() Will remove all training efforts - in other words all embeddings that are learnt for concepts in the current CDB. Please note that this does not remove synonyms (names) that were potentially added during supervised/online learning. .. py:method:: filter_by_cui(cuis_to_keep) Subset the core CDB fields (dictionaries/maps). Note that this will potenitally keep a bit more CUIs then in cuis_to_keep. It will first find all names that link to the cuis_to_keep and then find all CUIs that link to those names and keep all of them. This also will not remove any data from cdb.addl_info - as this field can contain data of unknown structure. :param cuis_to_keep: CUIs that will be kept, the rest will be removed (not completely, look above). :type cuis_to_keep: Collection[str] :raises Exception: If no snames and subsetting is not possible. .. py:method:: remove_cui(cui) This function takes a CUI and removes it the CDB. It also removes the CUI from name specific per_cui_status maps as well as well as removes all the names that do not correspond to any CUIs after the removal of this one. :param cui: The CUI to remove. :type cui: str .. py:method:: _remove_names(cui, names) Remove names from an existing concept - effect is this name will never again be used to link to this concept. This will only remove the name from the linker (namely name2cuis and name2cuis2status), the name will still be present everywhere else. Why? Because it is bothersome to remove it from everywhere, but could also be useful to keep the removed names in e.g. cui2names. :param cui: Concept ID or unique identifier in this database. :type cui: str :param names: Names to be removed (e.g list, set, or even a dict (in which case keys will be used)). :type names: Iterable[str] .. py:method:: __eq__(other) .. py:method:: get_cui2count_train() .. py:method:: get_name2count_train() .. py:method:: get_hash() .. py:method:: get_basic_info() .. py:method:: save(save_path, serialiser = AvailableSerialisers.dill, overwrite = False) Save CDB at path. :param save_path: The path to save at. :type save_path: str :param serialiser: The serialiser. Defaults to AvailableSerialisers.dill. :type serialiser: Union[ str, AvailableSerialisers], optional :param overwrite: Whether to allow overwriting existing files. Defaults to False. :type overwrite: bool, optional .. py:method:: load(path) :classmethod: .. py:method:: get_strategy() .. py:method:: ignore_attrs() :classmethod: .. py:method:: include_properties() :classmethod: .. py:class:: MedCATTrainerExport Bases: :py:obj:`typing_extensions.TypedDict` dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2) .. py:attribute:: projects :type: list[MedCATTrainerExportProject] .. py:method:: __contains__() True if the dictionary has the specified key, else False. .. py:method:: __delattr__() Implement delattr(self, name). .. py:method:: __delitem__() Delete self[key]. .. py:method:: __dir__() Default dir() implementation. .. py:method:: __eq__() Return self==value. .. py:method:: __format__() Default object formatter. .. py:method:: __ge__() Return self>=value. .. py:method:: __getattribute__() Return getattr(self, name). .. py:method:: __getitem__() x.__getitem__(y) <==> x[y] .. py:method:: __gt__() Return self>value. .. py:method:: __init__() Initialize self. See help(type(self)) for accurate signature. .. py:method:: __ior__() Return self|=value. .. py:method:: __iter__() Implement iter(self). .. py:method:: __le__() Return self<=value. .. py:method:: __len__() Return len(self). .. py:method:: __lt__() Return self size of D in memory, in bytes .. py:method:: __str__() Return str(self). .. py:method:: __subclasshook__() Abstract classes can override this to customize issubclass(). This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached). .. py:method:: clear() D.clear() -> None. Remove all items from D. .. py:method:: copy() D.copy() -> a shallow copy of D .. py:method:: get() Return the value for key if key is in the dictionary, else default. .. py:method:: items() D.items() -> a set-like object providing a view on D's items .. py:method:: keys() D.keys() -> a set-like object providing a view on D's keys .. py:method:: pop() D.pop(k[,d]) -> v, remove specified key and return the corresponding value. If the key is not found, return the default if given; otherwise, raise a KeyError. .. py:method:: popitem() Remove and return a (key, value) pair as a 2-tuple. Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty. .. py:method:: setdefault() Insert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default. .. py:method:: update() D.update([E, ]**F) -> None. Update D from dict/iterable E and F. If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k] .. py:method:: values() D.values() -> an object providing a view on D's values .. py:class:: MedCATTrainerExportProject Bases: :py:obj:`typing_extensions.TypedDict` dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2) .. py:attribute:: name :type: str .. py:attribute:: id :type: Any .. py:attribute:: cuis :type: str .. py:attribute:: tuis :type: Optional[str] .. py:attribute:: documents :type: list[MedCATTrainerExportDocument] .. py:method:: __contains__() True if the dictionary has the specified key, else False. .. py:method:: __delattr__() Implement delattr(self, name). .. py:method:: __delitem__() Delete self[key]. .. py:method:: __dir__() Default dir() implementation. .. py:method:: __eq__() Return self==value. .. py:method:: __format__() Default object formatter. .. py:method:: __ge__() Return self>=value. .. py:method:: __getattribute__() Return getattr(self, name). .. py:method:: __getitem__() x.__getitem__(y) <==> x[y] .. py:method:: __gt__() Return self>value. .. py:method:: __init__() Initialize self. See help(type(self)) for accurate signature. .. py:method:: __ior__() Return self|=value. .. py:method:: __iter__() Implement iter(self). .. py:method:: __le__() Return self<=value. .. py:method:: __len__() Return len(self). .. py:method:: __lt__() Return self size of D in memory, in bytes .. py:method:: __str__() Return str(self). .. py:method:: __subclasshook__() Abstract classes can override this to customize issubclass(). This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached). .. py:method:: clear() D.clear() -> None. Remove all items from D. .. py:method:: copy() D.copy() -> a shallow copy of D .. py:method:: get() Return the value for key if key is in the dictionary, else default. .. py:method:: items() D.items() -> a set-like object providing a view on D's items .. py:method:: keys() D.keys() -> a set-like object providing a view on D's keys .. py:method:: pop() D.pop(k[,d]) -> v, remove specified key and return the corresponding value. If the key is not found, return the default if given; otherwise, raise a KeyError. .. py:method:: popitem() Remove and return a (key, value) pair as a 2-tuple. Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty. .. py:method:: setdefault() Insert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default. .. py:method:: update() D.update([E, ]**F) -> None. Update D from dict/iterable E and F. If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k] .. py:method:: values() D.values() -> an object providing a view on D's values .. py:class:: MedCATTrainerExportDocument Bases: :py:obj:`typing_extensions.TypedDict` dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2) .. py:attribute:: name :type: str .. py:attribute:: id :type: Any .. py:attribute:: last_modified :type: str .. py:attribute:: text :type: str .. py:attribute:: annotations :type: list[MedCATTrainerExportAnnotation] .. py:method:: __contains__() True if the dictionary has the specified key, else False. .. py:method:: __delattr__() Implement delattr(self, name). .. py:method:: __delitem__() Delete self[key]. .. py:method:: __dir__() Default dir() implementation. .. py:method:: __eq__() Return self==value. .. py:method:: __format__() Default object formatter. .. py:method:: __ge__() Return self>=value. .. py:method:: __getattribute__() Return getattr(self, name). .. py:method:: __getitem__() x.__getitem__(y) <==> x[y] .. py:method:: __gt__() Return self>value. .. py:method:: __init__() Initialize self. See help(type(self)) for accurate signature. .. py:method:: __ior__() Return self|=value. .. py:method:: __iter__() Implement iter(self). .. py:method:: __le__() Return self<=value. .. py:method:: __len__() Return len(self). .. py:method:: __lt__() Return self size of D in memory, in bytes .. py:method:: __str__() Return str(self). .. py:method:: __subclasshook__() Abstract classes can override this to customize issubclass(). This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached). .. py:method:: clear() D.clear() -> None. Remove all items from D. .. py:method:: copy() D.copy() -> a shallow copy of D .. py:method:: get() Return the value for key if key is in the dictionary, else default. .. py:method:: items() D.items() -> a set-like object providing a view on D's items .. py:method:: keys() D.keys() -> a set-like object providing a view on D's keys .. py:method:: pop() D.pop(k[,d]) -> v, remove specified key and return the corresponding value. If the key is not found, return the default if given; otherwise, raise a KeyError. .. py:method:: popitem() Remove and return a (key, value) pair as a 2-tuple. Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty. .. py:method:: setdefault() Insert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default. .. py:method:: update() D.update([E, ]**F) -> None. Update D from dict/iterable E and F. If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k] .. py:method:: values() D.values() -> an object providing a view on D's values .. py:class:: MutableDocument Bases: :py:obj:`Protocol` The mutable parts of the document. Represents parts of the document that can / should be changed by the various components. .. py:property:: base :type: BaseDocument The base document. .. py:property:: linked_ents :type: list[MutableEntity] The linked entities associated with the document. This should be set by the linker. .. py:property:: ner_ents :type: list[MutableEntity] All entities recognised by NER. This should be set by the NER component. .. py:method:: __iter__() .. py:method:: __getitem__(index: int) -> MutableToken __getitem__(index: slice) -> MutableEntity .. py:method:: __len__() .. py:method:: get_tokens(start_index, end_index) Get the tokens that span the specified character indices. :param start_index: The starting character index. :type start_index: int :param end_index: The ending character index. :type end_index: int :Returns: **list[MutableToken]** -- The list of tokens. .. py:method:: set_addon_data(path, val) Used to add arbitrary data to the entity. This is generally used by addons to keep track of their data. NB! The path used needs to be registered using the `register_addon_path` class method. :param path: The data ID / path. :type path: str :param val: The value to be added. :type val: Any .. py:method:: has_addon_data(path) Checks whether the addon data for a specific path has been set. :param path: The path to check. :type path: str :Returns: **bool** -- Whether the addon data had been set. .. py:method:: get_addon_data(path) Get data added to the entity. See `add_data` for details. :param path: The data ID / path. :type path: str :Returns: **Any** -- The stored value. .. py:method:: get_available_addon_paths() Gets the available addon data paths for this document. This will only include paths that have values set. :Returns: **list[str]** -- List of available addon data paths. .. py:method:: register_addon_path(path, def_val = None, force = True) :classmethod: Register a custom/arbitrary data path. This can be used to store arbitrary data along with the entity for use in an addon (e.g MetaCAT). PS: If using this, it is important to use paths namespaced to the component you're using in order to avoid conflicts. :param path: The path to be used. Should be prefixed by component name (e.g `meta_cat_id` for an ID tied to the `meta_cat` addon) :type path: str :param def_val: Default value. Defaults to `None`. :type def_val: Any :param force: Whether to forcefully add the value. Defaults to True. :type force: bool .. py:attribute:: __slots__ :value: () .. py:attribute:: _is_protocol :value: True .. py:attribute:: _is_runtime_protocol :value: False .. py:method:: __init_subclass__(*args, **kwargs) :classmethod: .. py:method:: __class_getitem__(params) :classmethod: .. py:class:: MutableEntity Bases: :py:obj:`Protocol` The mutable part of an entity. This represent the changeable part of an entnity. That is, parts that should be changed by the various components. .. py:property:: base :type: BaseEntity The base / static entity part. .. py:property:: detected_name :type: str The detected name (if any) for this entity. This should be set by the NER component. .. py:method:: set_addon_data(path, val) Used to add arbitrary data to the entity. This is generally used by addons to keep track of their data. NB! The path used needs to be registered using the `register_addon_path` class method. :param path: The data ID / path. :type path: str :param val: The value to be added. :type val: Any .. py:method:: has_addon_data(path) Checks whether the addon data for a specific path has been set. :param path: The path to check. :type path: str :Returns: **bool** -- Whether the addon data had been set. .. py:method:: get_addon_data(path) Get data added to the entity. See `add_data` for details. :param path: The data ID / path. :type path: str :Returns: **Any** -- The stored value. .. py:method:: get_available_addon_paths() Gets the available addon data paths for this entity. This will only include paths that have values set. :Returns: **list[str]** -- List of available addon data paths. .. py:property:: link_candidates :type: list[str] The candidates for the detected name (if any) for this entity. This should be set by the NER component. .. py:property:: context_similarity :type: float The context similarity of the lnked entity. This should be set by the linker component. .. py:property:: confidence :type: float The confidence for the lnked entity. NOTE: This seems to be unused! .. py:property:: cui :type: str The CUI of the lnked entity. This should be set by the linker component. .. py:property:: id :type: int The ID of the entity within the document. This counts all the entities recognised, not just ones that were successfully linked. This should be set by the NER. .. py:method:: register_addon_path(path, def_val = None, force = True) :classmethod: Register a custom/arbitrary data path. This can be used to store arbitrary data along with the entity for use in an addon (e.g MetaCAT). PS: If using this, it is important to use paths namespaced to the component you're using in order to avoid conflicts. :param path: The path to be used. Should be prefixed by component name (e.g `meta_cat_id` for an ID tied to the `meta_cat` addon) :type path: str :param def_val: Default value. Defaults to `None`. :type def_val: Any :param force: Whether to forcefully add the value. Defaults to True. :type force: bool .. py:method:: __iter__() .. py:method:: __len__() .. py:attribute:: __slots__ :value: () .. py:attribute:: _is_protocol :value: True .. py:attribute:: _is_runtime_protocol :value: False .. py:method:: __init_subclass__(*args, **kwargs) :classmethod: .. py:method:: __class_getitem__(params) :classmethod: .. py:class:: TestTrainSplitter(data, cdb, test_size = 0.2) .. py:attribute:: MAX_TEST_FRACTION :value: 0.3 .. py:attribute:: MIN_CNT_FOR_TEST :value: 10 .. py:method:: __init__(data, cdb, test_size = 0.2) .. py:attribute:: data .. py:attribute:: cdb .. py:attribute:: test_size :value: 0.2 .. py:method:: _reset() .. py:method:: _count_project(project) .. py:method:: split() .. py:method:: _split_doc_train_test(document, cui_filter, train_project, test_project) .. py:method:: _should_add_to_test(_cnts) .. py:function:: make_mc_train_test(data, cdb, test_size = 0.2) Make train set. This is a disaster. :param data: The data. :type data: MedCATTrainerExport :param cdb: The concept database. :type cdb: CDB :param test_size: The test size. Defaults to 0.2. :type test_size: float :Returns: **tuple** -- The train set, the test set, the test annotations, and the total annotations .. py:function:: get_false_positives(doc, spacy_doc) Get the false positives within a trainer export. :param doc: The trainer export. :type doc: MedCATTrainerExportDocument :param spacy_doc: The annotated document. :type spacy_doc: MutableDocument :Returns: **list[MutableEntity]** -- The list of false positive entities.