mirror of
				https://github.com/explosion/spaCy.git
				synced 2025-10-31 07:57:35 +03:00 
			
		
		
		
	* Refactor Docs.is_ flags
* Add derived `Doc.has_annotation` method
  * `Doc.has_annotation(attr)` returns `True` for partial annotation
  * `Doc.has_annotation(attr, require_complete=True)` returns `True` for
    complete annotation
* Add deprecation warnings to `is_tagged`, `is_parsed`, `is_sentenced`
and `is_nered`
* Add `Doc._get_array_attrs()`, which returns a full list of `Doc` attrs
for use with `Doc.to_array`, `Doc.to_bytes` and `Doc.from_docs`. The
list is the `DocBin` attributes list plus `SPACY` and `LENGTH`.
Notes on `Doc.has_annotation`:
* `HEAD` is converted to `DEP` because heads don't have an unset state
* Accept `IS_SENT_START` as a synonym of `SENT_START`
Additional changes:
* Add `NORM`, `ENT_ID` and `SENT_START` to default attributes for
`DocBin`
* In `Doc.from_array()` the presence of `DEP` causes `HEAD` to override
`SENT_START`
* In `Doc.from_array()` using `attrs` other than
`Doc._get_array_attrs()` (i.e., a user's custom list rather than our
default internal list) with both `HEAD` and `SENT_START` shows a warning
that `HEAD` will override `SENT_START`
* `set_children_from_heads` does not require dependency labels to set
sentence boundaries and sets `sent_start` for all non-sentence starts to
`-1`
* Fix call to set_children_form_heads
Co-authored-by: Matthew Honnibal <honnibal+gh@gmail.com>
		
	
			
		
			
				
	
	
		
			40 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			40 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from typing import Union, Iterator
 | |
| 
 | |
| from ...symbols import NOUN, PROPN, PRON
 | |
| from ...errors import Errors
 | |
| from ...tokens import Doc, Span
 | |
| 
 | |
| 
 | |
| def noun_chunks(doclike: Union[Doc, Span]) -> Iterator[Span]:
 | |
|     """Detect base noun phrases from a dependency parse. Works on Doc and Span."""
 | |
|     # fmt: off
 | |
|     labels = ["nsubj", "nsubj:pass", "dobj", "obj", "iobj", "ROOT", "appos", "nmod", "nmod:poss"]
 | |
|     # fmt: on
 | |
|     doc = doclike.doc  # Ensure works on both Doc and Span.
 | |
|     if not doc.has_annotation("DEP"):
 | |
|         raise ValueError(Errors.E029)
 | |
|     np_deps = [doc.vocab.strings[label] for label in labels]
 | |
|     conj = doc.vocab.strings.add("conj")
 | |
|     np_label = doc.vocab.strings.add("NP")
 | |
|     prev_end = -1
 | |
|     for i, word in enumerate(doclike):
 | |
|         if word.pos not in (NOUN, PROPN, PRON):
 | |
|             continue
 | |
|         # Prevent nested chunks from being produced
 | |
|         if word.left_edge.i <= prev_end:
 | |
|             continue
 | |
|         if word.dep in np_deps:
 | |
|             prev_end = word.right_edge.i
 | |
|             yield word.left_edge.i, word.right_edge.i + 1, np_label
 | |
|         elif word.dep == conj:
 | |
|             head = word.head
 | |
|             while head.dep == conj and head.head.i < head.i:
 | |
|                 head = head.head
 | |
|             # If the head is an NP, and we're coordinated to it, we're an NP
 | |
|             if head.dep in np_deps:
 | |
|                 prev_end = word.right_edge.i
 | |
|                 yield word.left_edge.i, word.right_edge.i + 1, np_label
 | |
| 
 | |
| 
 | |
| SYNTAX_ITERATORS = {"noun_chunks": noun_chunks}
 |