chore: import upstream snapshot with attribution
tests / Test (macos-latest, 3.14) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.10) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.11) (push) Has been cancelled
tests / Test (windows-latest, 3.13) (push) Has been cancelled
tests / Test (windows-latest, 3.14) (push) Has been cancelled
tests / Validate (push) Has been cancelled
tests / Test (macos-latest, 3.10) (push) Has been cancelled
tests / Test (macos-latest, 3.11) (push) Has been cancelled
tests / Test (macos-latest, 3.12) (push) Has been cancelled
tests / Test (macos-latest, 3.13) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.12) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.13) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.14) (push) Has been cancelled
tests / Test (windows-latest, 3.10) (push) Has been cancelled
tests / Test (windows-latest, 3.11) (push) Has been cancelled
tests / Test (windows-latest, 3.12) (push) Has been cancelled
universe validation / Validate (push) Has been cancelled
tests / Test (macos-latest, 3.14) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.10) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.11) (push) Has been cancelled
tests / Test (windows-latest, 3.13) (push) Has been cancelled
tests / Test (windows-latest, 3.14) (push) Has been cancelled
tests / Validate (push) Has been cancelled
tests / Test (macos-latest, 3.10) (push) Has been cancelled
tests / Test (macos-latest, 3.11) (push) Has been cancelled
tests / Test (macos-latest, 3.12) (push) Has been cancelled
tests / Test (macos-latest, 3.13) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.12) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.13) (push) Has been cancelled
tests / Test (ubuntu-latest, 3.14) (push) Has been cancelled
tests / Test (windows-latest, 3.10) (push) Has been cancelled
tests / Test (windows-latest, 3.11) (push) Has been cancelled
tests / Test (windows-latest, 3.12) (push) Has been cancelled
universe validation / Validate (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
The central data structures in spaCy are the [`Language`](/api/language) class,
|
||||
the [`Vocab`](/api/vocab) and the [`Doc`](/api/doc) object. The `Language` class
|
||||
is used to process a text and turn it into a `Doc` object. It's typically stored
|
||||
as a variable called `nlp`. The `Doc` object owns the **sequence of tokens** and
|
||||
all their annotations. By centralizing strings, word vectors and lexical
|
||||
attributes in the `Vocab`, we avoid storing multiple copies of this data. This
|
||||
saves memory, and ensures there's a **single source of truth**.
|
||||
|
||||
Text annotations are also designed to allow a single source of truth: the `Doc`
|
||||
object owns the data, and [`Span`](/api/span) and [`Token`](/api/token) are
|
||||
**views that point into it**. The `Doc` object is constructed by the
|
||||
[`Tokenizer`](/api/tokenizer), and then **modified in place** by the components
|
||||
of the pipeline. The `Language` object coordinates these components. It takes
|
||||
raw text and sends it through the pipeline, returning an **annotated document**.
|
||||
It also orchestrates training and serialization.
|
||||
|
||||

|
||||
|
||||
### Container objects {id="architecture-containers"}
|
||||
|
||||
| Name | Description |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [`Doc`](/api/doc) | A container for accessing linguistic annotations. |
|
||||
| [`DocBin`](/api/docbin) | A collection of `Doc` objects for efficient binary serialization. Also used for [training data](/api/data-formats#binary-training). |
|
||||
| [`Example`](/api/example) | A collection of training annotations, containing two `Doc` objects: the reference data and the predictions. |
|
||||
| [`Language`](/api/language) | Processing class that turns text into `Doc` objects. Different languages implement their own subclasses of it. The variable is typically called `nlp`. |
|
||||
| [`Lexeme`](/api/lexeme) | An entry in the vocabulary. It's a word type with no context, as opposed to a word token. It therefore has no part-of-speech tag, dependency parse etc. |
|
||||
| [`Span`](/api/span) | A slice from a `Doc` object. |
|
||||
| [`SpanGroup`](/api/spangroup) | A named collection of spans belonging to a `Doc`. |
|
||||
| [`Token`](/api/token) | An individual token — i.e. a word, punctuation symbol, whitespace, etc. |
|
||||
|
||||
### Processing pipeline {id="architecture-pipeline"}
|
||||
|
||||
The processing pipeline consists of one or more **pipeline components** that are
|
||||
called on the `Doc` in order. The tokenizer runs before the components. Pipeline
|
||||
components can be added using [`Language.add_pipe`](/api/language#add_pipe).
|
||||
They can contain a statistical model and trained weights, or only make
|
||||
rule-based modifications to the `Doc`. spaCy provides a range of built-in
|
||||
components for different language processing tasks and also allows adding
|
||||
[custom components](/usage/processing-pipelines#custom-components).
|
||||
|
||||

|
||||
|
||||
| Name | Description |
|
||||
| ----------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| [`AttributeRuler`](/api/attributeruler) | Set token attributes using matcher rules. |
|
||||
| [`DependencyParser`](/api/dependencyparser) | Predict syntactic dependencies. |
|
||||
| [`EditTreeLemmatizer`](/api/edittreelemmatizer) | Predict base forms of words. |
|
||||
| [`EntityLinker`](/api/entitylinker) | Disambiguate named entities to nodes in a knowledge base. |
|
||||
| [`EntityRecognizer`](/api/entityrecognizer) | Predict named entities, e.g. persons or products. |
|
||||
| [`EntityRuler`](/api/entityruler) | Add entity spans to the `Doc` using token-based rules or exact phrase matches. |
|
||||
| [`Lemmatizer`](/api/lemmatizer) | Determine the base forms of words using rules and lookups. |
|
||||
| [`Morphologizer`](/api/morphologizer) | Predict morphological features and coarse-grained part-of-speech tags. |
|
||||
| [`SentenceRecognizer`](/api/sentencerecognizer) | Predict sentence boundaries. |
|
||||
| [`Sentencizer`](/api/sentencizer) | Implement rule-based sentence boundary detection that doesn't require the dependency parse. |
|
||||
| [`Tagger`](/api/tagger) | Predict part-of-speech tags. |
|
||||
| [`TextCategorizer`](/api/textcategorizer) | Predict categories or labels over the whole document. |
|
||||
| [`Tok2Vec`](/api/tok2vec) | Apply a "token-to-vector" model and set its outputs. |
|
||||
| [`Tokenizer`](/api/tokenizer) | Segment raw text and create `Doc` objects from the words. |
|
||||
| [`TrainablePipe`](/api/pipe) | Class that all trainable pipeline components inherit from. |
|
||||
| [`Transformer`](/api/transformer) | Use a transformer model and set its outputs. |
|
||||
| [Other functions](/api/pipeline-functions) | Automatically apply something to the `Doc`, e.g. to merge spans of tokens. |
|
||||
|
||||
### Matchers {id="architecture-matchers"}
|
||||
|
||||
Matchers help you find and extract information from [`Doc`](/api/doc) objects
|
||||
based on match patterns describing the sequences you're looking for. A matcher
|
||||
operates on a `Doc` and gives you access to the matched tokens **in context**.
|
||||
|
||||
| Name | Description |
|
||||
| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [`DependencyMatcher`](/api/dependencymatcher) | Match sequences of tokens based on dependency trees using [Semgrex operators](https://nlp.stanford.edu/nlp/javadoc/javanlp/edu/stanford/nlp/semgraph/semgrex/SemgrexPattern.html). |
|
||||
| [`Matcher`](/api/matcher) | Match sequences of tokens, based on pattern rules, similar to regular expressions. |
|
||||
| [`PhraseMatcher`](/api/phrasematcher) | Match sequences of tokens based on phrases. |
|
||||
|
||||
### Other classes {id="architecture-other"}
|
||||
|
||||
| Name | Description |
|
||||
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
|
||||
| [`Corpus`](/api/corpus) | Class for managing annotated corpora for training and evaluation data. |
|
||||
| [`KnowledgeBase`](/api/kb) | Abstract base class for storage and retrieval of data for entity linking. |
|
||||
| [`InMemoryLookupKB`](/api/inmemorylookupkb) | Implementation of `KnowledgeBase` storing all data in memory. |
|
||||
| [`Candidate`](/api/kb#candidate) | Object associating a textual mention with a specific entity contained in a `KnowledgeBase`. |
|
||||
| [`Lookups`](/api/lookups) | Container for convenient access to large lookup tables and dictionaries. |
|
||||
| [`MorphAnalysis`](/api/morphology#morphanalysis) | A morphological analysis. |
|
||||
| [`Morphology`](/api/morphology) | Store morphological analyses and map them to and from hash values. |
|
||||
| [`Scorer`](/api/scorer) | Compute evaluation scores. |
|
||||
| [`StringStore`](/api/stringstore) | Map strings to and from hash values. |
|
||||
| [`Vectors`](/api/vectors) | Container class for vector data keyed by string. |
|
||||
| [`Vocab`](/api/vocab) | The shared vocabulary that stores strings and gives you access to [`Lexeme`](/api/lexeme) objects. |
|
||||
@@ -0,0 +1,32 @@
|
||||
Every language is different – and usually full of **exceptions and special
|
||||
cases**, especially amongst the most common words. Some of these exceptions are
|
||||
shared across languages, while others are **entirely specific** – usually so
|
||||
specific that they need to be hard-coded. The
|
||||
[`lang`](%%GITHUB_SPACY/spacy/lang) module contains all language-specific data,
|
||||
organized in simple Python files. This makes the data easy to update and extend.
|
||||
|
||||
The **shared language data** in the directory root includes rules that can be
|
||||
generalized across languages – for example, rules for basic punctuation, emoji,
|
||||
emoticons and single-letter abbreviations. The **individual language data** in a
|
||||
submodule contains rules that are only relevant to a particular language. It
|
||||
also takes care of putting together all components and creating the
|
||||
[`Language`](/api/language) subclass – for example, `English` or `German`. The
|
||||
values are defined in the [`Language.Defaults`](/api/language#defaults).
|
||||
|
||||
> ```python
|
||||
> from spacy.lang.en import English
|
||||
> from spacy.lang.de import German
|
||||
>
|
||||
> nlp_en = English() # Includes English data
|
||||
> nlp_de = German() # Includes German data
|
||||
> ```
|
||||
|
||||
| Name | Description |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Stop words**<br />[`stop_words.py`](%%GITHUB_SPACY/spacy/lang/en/stop_words.py) | List of most common words of a language that are often useful to filter out, for example "and" or "I". Matching tokens will return `True` for `is_stop`. |
|
||||
| **Tokenizer exceptions**<br />[`tokenizer_exceptions.py`](%%GITHUB_SPACY/spacy/lang/de/tokenizer_exceptions.py) | Special-case rules for the tokenizer, for example, contractions like "can't" and abbreviations with punctuation, like "U.K.". |
|
||||
| **Punctuation rules**<br />[`punctuation.py`](%%GITHUB_SPACY/spacy/lang/punctuation.py) | Regular expressions for splitting tokens, e.g. on punctuation or special characters like emoji. Includes rules for prefixes, suffixes and infixes. |
|
||||
| **Character classes**<br />[`char_classes.py`](%%GITHUB_SPACY/spacy/lang/char_classes.py) | Character classes to be used in regular expressions, for example, Latin characters, quotes, hyphens or icons. |
|
||||
| **Lexical attributes**<br />[`lex_attrs.py`](%%GITHUB_SPACY/spacy/lang/en/lex_attrs.py) | Custom functions for setting lexical attributes on tokens, e.g. `like_num`, which includes language-specific words like "ten" or "hundred". |
|
||||
| **Syntax iterators**<br />[`syntax_iterators.py`](%%GITHUB_SPACY/spacy/lang/en/syntax_iterators.py) | Functions that compute views of a `Doc` object based on its syntax. At the moment, only used for [noun chunks](/usage/linguistic-features#noun-chunks). |
|
||||
| **Lemmatizer**<br />[`lemmatizer.py`](%%GITHUB_SPACY/spacy/lang/fr/lemmatizer.py) [`spacy-lookups-data`](https://github.com/explosion/spacy-lookups-data) | Custom lemmatizer implementation and lemmatization tables. |
|
||||
@@ -0,0 +1,36 @@
|
||||
A named entity is a "real-world object" that's assigned a name – for example, a
|
||||
person, a country, a product or a book title. spaCy can **recognize various
|
||||
types of named entities in a document, by asking the model for a prediction**.
|
||||
Because models are statistical and strongly depend on the examples they were
|
||||
trained on, this doesn't always work _perfectly_ and might need some tuning
|
||||
later, depending on your use case.
|
||||
|
||||
Named entities are available as the `ents` property of a `Doc`:
|
||||
|
||||
```python {executable="true"}
|
||||
import spacy
|
||||
|
||||
nlp = spacy.load("en_core_web_sm")
|
||||
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
|
||||
|
||||
for ent in doc.ents:
|
||||
print(ent.text, ent.start_char, ent.end_char, ent.label_)
|
||||
```
|
||||
|
||||
> - **Text:** The original entity text.
|
||||
> - **Start:** Index of start of entity in the `Doc`.
|
||||
> - **End:** Index of end of entity in the `Doc`.
|
||||
> - **Label:** Entity label, i.e. type.
|
||||
|
||||
| Text | Start | End | Label | Description |
|
||||
| ----------- | :---: | :-: | ------- | ---------------------------------------------------- |
|
||||
| Apple | 0 | 5 | `ORG` | Companies, agencies, institutions. |
|
||||
| U.K. | 27 | 31 | `GPE` | Geopolitical entity, i.e. countries, cities, states. |
|
||||
| \$1 billion | 44 | 54 | `MONEY` | Monetary values, including unit. |
|
||||
|
||||
Using spaCy's built-in [displaCy visualizer](/usage/visualizers), here's what
|
||||
our example sentence and its named entities look like:
|
||||
|
||||
<Standalone height={120}>
|
||||
<div style={{lineHeight: 2.5, fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'", fontSize: 18}}><mark style={{ background: '#7aecec', padding: '0.45em 0.6em', margin: '0 0.25em', lineHeight: 1, borderRadius: '0.35em'}}>Apple <span style={{ fontSize: '0.8em', fontWeight: 'bold', lineHeight: 1, borderRadius: '0.35em', marginLeft: '0.5rem'}}>ORG</span></mark> is looking at buying <mark style={{ background: '#feca74', padding: '0.45em 0.6em', margin: '0 0.25em', lineHeight: 1, borderRadius: '0.35em'}}>U.K. <span style={{ fontSize: '0.8em', fontWeight: 'bold', lineHeight: 1, borderRadius: '0.35em', marginLeft: '0.5rem'}}>GPE</span></mark> startup for <mark style={{ background: '#e4e7d2', padding: '0.45em 0.6em', margin: '0 0.25em', lineHeight: 1, borderRadius: '0.35em'}}>$1 billion <span style={{ fontSize: '0.8em', fontWeight: 'bold', lineHeight: 1, borderRadius: '0.35em', marginLeft: '0.5rem'}}>MONEY</span></mark></div>
|
||||
</Standalone>
|
||||
@@ -0,0 +1,77 @@
|
||||
When you call `nlp` on a text, spaCy first tokenizes the text to produce a `Doc`
|
||||
object. The `Doc` is then processed in several different steps – this is also
|
||||
referred to as the **processing pipeline**. The pipeline used by the
|
||||
[trained pipelines](/models) typically include a tagger, a lemmatizer, a parser
|
||||
and an entity recognizer. Each pipeline component returns the processed `Doc`,
|
||||
which is then passed on to the next component.
|
||||
|
||||

|
||||
|
||||
> - **Name**: ID of the pipeline component.
|
||||
> - **Component:** spaCy's implementation of the component.
|
||||
> - **Creates:** Objects, attributes and properties modified and set by the
|
||||
> component.
|
||||
|
||||
| Name | Component | Creates | Description |
|
||||
| --------------------- | ------------------------------------------------------------------ | --------------------------------------------------------- | ------------------------------------------------ |
|
||||
| **tokenizer** | [`Tokenizer`](/api/tokenizer) | `Doc` | Segment text into tokens. |
|
||||
| _processing pipeline_ | | |
|
||||
| **tagger** | [`Tagger`](/api/tagger) | `Token.tag` | Assign part-of-speech tags. |
|
||||
| **parser** | [`DependencyParser`](/api/dependencyparser) | `Token.head`, `Token.dep`, `Doc.sents`, `Doc.noun_chunks` | Assign dependency labels. |
|
||||
| **ner** | [`EntityRecognizer`](/api/entityrecognizer) | `Doc.ents`, `Token.ent_iob`, `Token.ent_type` | Detect and label named entities. |
|
||||
| **lemmatizer** | [`Lemmatizer`](/api/lemmatizer) | `Token.lemma` | Assign base forms. |
|
||||
| **textcat** | [`TextCategorizer`](/api/textcategorizer) | `Doc.cats` | Assign document labels. |
|
||||
| **custom** | [custom components](/usage/processing-pipelines#custom-components) | `Doc._.xxx`, `Token._.xxx`, `Span._.xxx` | Assign custom attributes, methods or properties. |
|
||||
|
||||
The capabilities of a processing pipeline always depend on the components, their
|
||||
models and how they were trained. For example, a pipeline for named entity
|
||||
recognition needs to include a trained named entity recognizer component with a
|
||||
statistical model and weights that enable it to **make predictions** of entity
|
||||
labels. This is why each pipeline specifies its components and their settings in
|
||||
the [config](/usage/training#config):
|
||||
|
||||
```ini
|
||||
[nlp]
|
||||
pipeline = ["tok2vec", "tagger", "parser", "ner"]
|
||||
```
|
||||
|
||||
<Accordion title="Does the order of pipeline components matter?" id="pipeline-components-order">
|
||||
|
||||
The statistical components like the tagger or parser are typically independent
|
||||
and don't share any data between each other. For example, the named entity
|
||||
recognizer doesn't use any features set by the tagger and parser, and so on.
|
||||
This means that you can swap them, or remove single components from the pipeline
|
||||
without affecting the others. However, components may share a "token-to-vector"
|
||||
component like [`Tok2Vec`](/api/tok2vec) or [`Transformer`](/api/transformer).
|
||||
You can read more about this in the docs on
|
||||
[embedding layers](/usage/embeddings-transformers#embedding-layers).
|
||||
|
||||
Custom components may also depend on annotations set by other components. For
|
||||
example, a custom lemmatizer may need the part-of-speech tags assigned, so it'll
|
||||
only work if it's added after the tagger. The parser will respect pre-defined
|
||||
sentence boundaries, so if a previous component in the pipeline sets them, its
|
||||
dependency predictions may be different. Similarly, it matters if you add the
|
||||
[`EntityRuler`](/api/entityruler) before or after the statistical entity
|
||||
recognizer: if it's added before, the entity recognizer will take the existing
|
||||
entities into account when making predictions. The
|
||||
[`EntityLinker`](/api/entitylinker), which resolves named entities to knowledge
|
||||
base IDs, should be preceded by a pipeline component that recognizes entities
|
||||
such as the [`EntityRecognizer`](/api/entityrecognizer).
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Why is the tokenizer special?" id="pipeline-components-tokenizer">
|
||||
|
||||
The tokenizer is a "special" component and isn't part of the regular pipeline.
|
||||
It also doesn't show up in `nlp.pipe_names`. The reason is that there can only
|
||||
really be one tokenizer, and while all other pipeline components take a `Doc`
|
||||
and return it, the tokenizer takes a **string of text** and turns it into a
|
||||
`Doc`. You can still customize the tokenizer, though. `nlp.tokenizer` is
|
||||
writable, so you can either create your own
|
||||
[`Tokenizer` class from scratch](/usage/linguistic-features#native-tokenizers),
|
||||
or even replace it with an
|
||||
[entirely custom function](/usage/linguistic-features#custom-tokenizer).
|
||||
|
||||
</Accordion>
|
||||
|
||||
---
|
||||
@@ -0,0 +1,62 @@
|
||||
After tokenization, spaCy can **parse** and **tag** a given `Doc`. This is where
|
||||
the trained pipeline and its statistical models come in, which enable spaCy to
|
||||
**make predictions** of which tag or label most likely applies in this context.
|
||||
A trained component includes binary data that is produced by showing a system
|
||||
enough examples for it to make predictions that generalize across the language –
|
||||
for example, a word following "the" in English is most likely a noun.
|
||||
|
||||
Linguistic annotations are available as
|
||||
[`Token` attributes](/api/token#attributes). Like many NLP libraries, spaCy
|
||||
**encodes all strings to hash values** to reduce memory usage and improve
|
||||
efficiency. So to get the readable string representation of an attribute, we
|
||||
need to add an underscore `_` to its name:
|
||||
|
||||
```python {executable="true"}
|
||||
import spacy
|
||||
|
||||
nlp = spacy.load("en_core_web_sm")
|
||||
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
|
||||
|
||||
for token in doc:
|
||||
print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_,
|
||||
token.shape_, token.is_alpha, token.is_stop)
|
||||
```
|
||||
|
||||
> - **Text:** The original word text.
|
||||
> - **Lemma:** The base form of the word.
|
||||
> - **POS:** The simple [UPOS](https://universaldependencies.org/u/pos/)
|
||||
> part-of-speech tag.
|
||||
> - **Tag:** The detailed part-of-speech tag.
|
||||
> - **Dep:** Syntactic dependency, i.e. the relation between tokens.
|
||||
> - **Shape:** The word shape – capitalization, punctuation, digits.
|
||||
> - **is alpha:** Is the token an alpha character?
|
||||
> - **is stop:** Is the token part of a stop list, i.e. the most common words of
|
||||
> the language?
|
||||
|
||||
| Text | Lemma | POS | Tag | Dep | Shape | alpha | stop |
|
||||
| ------- | ------- | ------- | ----- | ---------- | ------- | ------- | ------- |
|
||||
| Apple | apple | `PROPN` | `NNP` | `nsubj` | `Xxxxx` | `True` | `False` |
|
||||
| is | be | `AUX` | `VBZ` | `aux` | `xx` | `True` | `True` |
|
||||
| looking | look | `VERB` | `VBG` | `ROOT` | `xxxx` | `True` | `False` |
|
||||
| at | at | `ADP` | `IN` | `prep` | `xx` | `True` | `True` |
|
||||
| buying | buy | `VERB` | `VBG` | `pcomp` | `xxxx` | `True` | `False` |
|
||||
| U.K. | u.k. | `PROPN` | `NNP` | `compound` | `X.X.` | `False` | `False` |
|
||||
| startup | startup | `NOUN` | `NN` | `dobj` | `xxxx` | `True` | `False` |
|
||||
| for | for | `ADP` | `IN` | `prep` | `xxx` | `True` | `True` |
|
||||
| \$ | \$ | `SYM` | `$` | `quantmod` | `$` | `False` | `False` |
|
||||
| 1 | 1 | `NUM` | `CD` | `compound` | `d` | `False` | `False` |
|
||||
| billion | billion | `NUM` | `CD` | `pobj` | `xxxx` | `True` | `False` |
|
||||
|
||||
> #### Tip: Understanding tags and labels
|
||||
>
|
||||
> Most of the tags and labels look pretty abstract, and they vary between
|
||||
> languages. `spacy.explain` will show you a short description – for example,
|
||||
> `spacy.explain("VBZ")` returns "verb, 3rd person singular present".
|
||||
|
||||
Using spaCy's built-in [displaCy visualizer](/usage/visualizers), here's what
|
||||
our example sentence and its dependencies look like:
|
||||
|
||||
<ImageScrollable
|
||||
src="/images/displacy-long.svg"
|
||||
width={1975}
|
||||
/>
|
||||
@@ -0,0 +1,29 @@
|
||||
If you've been modifying the pipeline, vocabulary, vectors and entities, or made
|
||||
updates to the component models, you'll eventually want to **save your
|
||||
progress** – for example, everything that's in your `nlp` object. This means
|
||||
you'll have to translate its contents and structure into a format that can be
|
||||
saved, like a file or a byte string. This process is called serialization. spaCy
|
||||
comes with **built-in serialization methods** and supports the
|
||||
[Pickle protocol](https://www.diveinto.org/python3/serializing.html#dump).
|
||||
|
||||
> #### What's pickle?
|
||||
>
|
||||
> Pickle is Python's built-in object persistence system. It lets you transfer
|
||||
> arbitrary Python objects between processes. This is usually used to load an
|
||||
> object to and from disk, but it's also used for distributed computing, e.g.
|
||||
> with
|
||||
> [PySpark](https://spark.apache.org/docs/0.9.0/python-programming-guide.html)
|
||||
> or [Dask](https://dask.org). When you unpickle an object, you're agreeing to
|
||||
> execute whatever code it contains. It's like calling `eval()` on a string – so
|
||||
> don't unpickle objects from untrusted sources.
|
||||
|
||||
All container classes, i.e. [`Language`](/api/language) (`nlp`),
|
||||
[`Doc`](/api/doc), [`Vocab`](/api/vocab) and [`StringStore`](/api/stringstore)
|
||||
have the following methods available:
|
||||
|
||||
| Method | Returns | Example |
|
||||
| ------------ | ------- | ------------------------ |
|
||||
| `to_bytes` | bytes | `data = nlp.to_bytes()` |
|
||||
| `from_bytes` | object | `nlp.from_bytes(data)` |
|
||||
| `to_disk` | - | `nlp.to_disk("/path")` |
|
||||
| `from_disk` | object | `nlp.from_disk("/path")` |
|
||||
@@ -0,0 +1,49 @@
|
||||
During processing, spaCy first **tokenizes** the text, i.e. segments it into
|
||||
words, punctuation and so on. This is done by applying rules specific to each
|
||||
language. For example, punctuation at the end of a sentence should be split off
|
||||
– whereas "U.K." should remain one token. Each `Doc` consists of individual
|
||||
tokens, and we can iterate over them:
|
||||
|
||||
```python {executable="true"}
|
||||
import spacy
|
||||
|
||||
nlp = spacy.load("en_core_web_sm")
|
||||
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
|
||||
for token in doc:
|
||||
print(token.text)
|
||||
```
|
||||
|
||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|
||||
| :---: | :-: | :-----: | :-: | :----: | :--: | :-----: | :-: | :-: | :-: | :-----: |
|
||||
| Apple | is | looking | at | buying | U.K. | startup | for | \$ | 1 | billion |
|
||||
|
||||
First, the raw text is split on whitespace characters, similar to
|
||||
`text.split(' ')`. Then, the tokenizer processes the text from left to right. On
|
||||
each substring, it performs two checks:
|
||||
|
||||
1. **Does the substring match a tokenizer exception rule?** For example, "don't"
|
||||
does not contain whitespace, but should be split into two tokens, "do" and
|
||||
"n't", while "U.K." should always remain one token.
|
||||
|
||||
2. **Can a prefix, suffix or infix be split off?** For example punctuation like
|
||||
commas, periods, hyphens or quotes.
|
||||
|
||||
If there's a match, the rule is applied and the tokenizer continues its loop,
|
||||
starting with the newly split substrings. This way, spaCy can split **complex,
|
||||
nested tokens** like combinations of abbreviations and multiple punctuation
|
||||
marks.
|
||||
|
||||
> - **Tokenizer exception:** Special-case rule to split a string into several
|
||||
> tokens or prevent a token from being split when punctuation rules are
|
||||
> applied.
|
||||
> - **Prefix:** Character(s) at the beginning, e.g. `$`, `(`, `“`, `¿`.
|
||||
> - **Suffix:** Character(s) at the end, e.g. `km`, `)`, `”`, `!`.
|
||||
> - **Infix:** Character(s) in between, e.g. `-`, `--`, `/`, `…`.
|
||||
|
||||

|
||||
|
||||
While punctuation rules are usually pretty general, tokenizer exceptions
|
||||
strongly depend on the specifics of the individual language. This is why each
|
||||
[available language](/usage/models#languages) has its own subclass, like
|
||||
`English` or `German`, that loads in lists of hard-coded data and exception
|
||||
rules.
|
||||
@@ -0,0 +1,41 @@
|
||||
spaCy's tagger, parser, text categorizer and many other components are powered
|
||||
by **statistical models**. Every "decision" these components make – for example,
|
||||
which part-of-speech tag to assign, or whether a word is a named entity – is a
|
||||
**prediction** based on the model's current **weight values**. The weight values
|
||||
are estimated based on examples the model has seen during **training**. To train
|
||||
a model, you first need training data – examples of text, and the labels you
|
||||
want the model to predict. This could be a part-of-speech tag, a named entity or
|
||||
any other information.
|
||||
|
||||
Training is an iterative process in which the model's predictions are compared
|
||||
against the reference annotations in order to estimate the **gradient of the
|
||||
loss**. The gradient of the loss is then used to calculate the gradient of the
|
||||
weights through [backpropagation](https://thinc.ai/docs/backprop101). The
|
||||
gradients indicate how the weight values should be changed so that the model's
|
||||
predictions become more similar to the reference labels over time.
|
||||
|
||||
> - **Training data:** Examples and their annotations.
|
||||
> - **Text:** The input text the model should predict a label for.
|
||||
> - **Label:** The label the model should predict.
|
||||
> - **Gradient:** The direction and rate of change for a numeric value.
|
||||
> Minimising the gradient of the weights should result in predictions that are
|
||||
> closer to the reference labels on the training data.
|
||||
|
||||

|
||||
|
||||
When training a model, we don't just want it to memorize our examples – we want
|
||||
it to come up with a theory that can be **generalized across unseen data**.
|
||||
After all, we don't just want the model to learn that this one instance of
|
||||
"Amazon" right here is a company – we want it to learn that "Amazon", in
|
||||
contexts _like this_, is most likely a company. That's why the training data
|
||||
should always be representative of the data we want to process. A model trained
|
||||
on Wikipedia, where sentences in the first person are extremely rare, will
|
||||
likely perform badly on Twitter. Similarly, a model trained on romantic novels
|
||||
will likely perform badly on legal text.
|
||||
|
||||
This also means that in order to know how the model is performing, and whether
|
||||
it's learning the right things, you don't only need **training data** – you'll
|
||||
also need **evaluation data**. If you only test the model with the data it was
|
||||
trained on, you'll have no idea how well it's generalizing. If you want to train
|
||||
a model from scratch, you usually need at least a few hundred examples for both
|
||||
training and evaluation.
|
||||
@@ -0,0 +1,150 @@
|
||||
Similarity is determined by comparing **word vectors** or "word embeddings",
|
||||
multi-dimensional meaning representations of a word. Word vectors can be
|
||||
generated using an algorithm like
|
||||
[word2vec](https://en.wikipedia.org/wiki/Word2vec) and usually look like this:
|
||||
|
||||
```python {title="banana.vector"}
|
||||
array([2.02280000e-01, -7.66180009e-02, 3.70319992e-01,
|
||||
3.28450017e-02, -4.19569999e-01, 7.20689967e-02,
|
||||
-3.74760002e-01, 5.74599989e-02, -1.24009997e-02,
|
||||
5.29489994e-01, -5.23800015e-01, -1.97710007e-01,
|
||||
-3.41470003e-01, 5.33169985e-01, -2.53309999e-02,
|
||||
1.73800007e-01, 1.67720005e-01, 8.39839995e-01,
|
||||
5.51070012e-02, 1.05470002e-01, 3.78719985e-01,
|
||||
2.42750004e-01, 1.47449998e-02, 5.59509993e-01,
|
||||
1.25210002e-01, -6.75960004e-01, 3.58420014e-01,
|
||||
# ... and so on ...
|
||||
3.66849989e-01, 2.52470002e-03, -6.40089989e-01,
|
||||
-2.97650009e-01, 7.89430022e-01, 3.31680000e-01,
|
||||
-1.19659996e+00, -4.71559986e-02, 5.31750023e-01], dtype=float32)
|
||||
```
|
||||
|
||||
<Infobox title="Important note" variant="warning">
|
||||
|
||||
To make them compact and fast, spaCy's small [pipeline packages](/models) (all
|
||||
packages that end in `sm`) **don't ship with word vectors**, and only include
|
||||
context-sensitive **tensors**. This means you can still use the `similarity()`
|
||||
methods to compare documents, spans and tokens – but the result won't be as
|
||||
good, and individual tokens won't have any vectors assigned. So in order to use
|
||||
_real_ word vectors, you need to download a larger pipeline package:
|
||||
|
||||
```diff
|
||||
- python -m spacy download en_core_web_sm
|
||||
+ python -m spacy download en_core_web_lg
|
||||
```
|
||||
|
||||
</Infobox>
|
||||
|
||||
Pipeline packages that come with built-in word vectors make them available as
|
||||
the [`Token.vector`](/api/token#vector) attribute.
|
||||
[`Doc.vector`](/api/doc#vector) and [`Span.vector`](/api/span#vector) will
|
||||
default to an average of their token vectors. You can also check if a token has
|
||||
a vector assigned, and get the L2 norm, which can be used to normalize vectors.
|
||||
|
||||
```python {executable="true"}
|
||||
import spacy
|
||||
|
||||
nlp = spacy.load("en_core_web_md")
|
||||
tokens = nlp("dog cat banana afskfsd")
|
||||
|
||||
for token in tokens:
|
||||
print(token.text, token.has_vector, token.vector_norm, token.is_oov)
|
||||
```
|
||||
|
||||
> - **Text**: The original token text.
|
||||
> - **has vector**: Does the token have a vector representation?
|
||||
> - **Vector norm**: The L2 norm of the token's vector (the square root of the
|
||||
> sum of the values squared)
|
||||
> - **OOV**: Out-of-vocabulary
|
||||
|
||||
The words "dog", "cat" and "banana" are all pretty common in English, so they're
|
||||
part of the pipeline's vocabulary, and come with a vector. The word "afskfsd" on
|
||||
the other hand is a lot less common and out-of-vocabulary – so its vector
|
||||
representation consists of 300 dimensions of `0`, which means it's practically
|
||||
nonexistent. If your application will benefit from a **large vocabulary** with
|
||||
more vectors, you should consider using one of the larger pipeline packages or
|
||||
loading in a full vector package, for example,
|
||||
[`en_core_web_lg`](/models/en#en_core_web_lg), which includes **685k unique
|
||||
vectors**.
|
||||
|
||||
spaCy is able to compare two objects, and make a prediction of **how similar
|
||||
they are**. Predicting similarity is useful for building recommendation systems
|
||||
or flagging duplicates. For example, you can suggest a user content that's
|
||||
similar to what they're currently looking at, or label a support ticket as a
|
||||
duplicate if it's very similar to an already existing one.
|
||||
|
||||
Each [`Doc`](/api/doc), [`Span`](/api/span), [`Token`](/api/token) and
|
||||
[`Lexeme`](/api/lexeme) comes with a [`.similarity`](/api/token#similarity)
|
||||
method that lets you compare it with another object, and determine the
|
||||
similarity. Of course similarity is always subjective – whether two words, spans
|
||||
or documents are similar really depends on how you're looking at it. spaCy's
|
||||
similarity implementation usually assumes a pretty general-purpose definition of
|
||||
similarity.
|
||||
|
||||
> #### 📝 Things to try
|
||||
>
|
||||
> 1. Compare two different tokens and try to find the two most _dissimilar_
|
||||
> tokens in the texts with the lowest similarity score (according to the
|
||||
> vectors).
|
||||
> 2. Compare the similarity of two [`Lexeme`](/api/lexeme) objects, entries in
|
||||
> the vocabulary. You can get a lexeme via the `.lex` attribute of a token.
|
||||
> You should see that the similarity results are identical to the token
|
||||
> similarity.
|
||||
|
||||
```python {executable="true"}
|
||||
import spacy
|
||||
|
||||
nlp = spacy.load("en_core_web_md") # make sure to use larger package!
|
||||
doc1 = nlp("I like salty fries and hamburgers.")
|
||||
doc2 = nlp("Fast food tastes very good.")
|
||||
|
||||
# Similarity of two documents
|
||||
print(doc1, "<->", doc2, doc1.similarity(doc2))
|
||||
# Similarity of tokens and spans
|
||||
french_fries = doc1[2:4]
|
||||
burgers = doc1[5]
|
||||
print(french_fries, "<->", burgers, french_fries.similarity(burgers))
|
||||
```
|
||||
|
||||
### What to expect from similarity results {id="similarity-expectations"}
|
||||
|
||||
Computing similarity scores can be helpful in many situations, but it's also
|
||||
important to maintain **realistic expectations** about what information it can
|
||||
provide. Words can be related to each other in many ways, so a single
|
||||
"similarity" score will always be a **mix of different signals**, and vectors
|
||||
trained on different data can produce very different results that may not be
|
||||
useful for your purpose. Here are some important considerations to keep in mind:
|
||||
|
||||
- There's no objective definition of similarity. Whether "I like burgers" and "I
|
||||
like pasta" is similar **depends on your application**. Both talk about food
|
||||
preferences, which makes them very similar – but if you're analyzing mentions
|
||||
of food, those sentences are pretty dissimilar, because they talk about very
|
||||
different foods.
|
||||
- The similarity of [`Doc`](/api/doc) and [`Span`](/api/span) objects defaults
|
||||
to the **average** of the token vectors. This means that the vector for "fast
|
||||
food" is the average of the vectors for "fast" and "food", which isn't
|
||||
necessarily representative of the phrase "fast food".
|
||||
- Vector averaging means that the vector of multiple tokens is **insensitive to
|
||||
the order** of the words. Two documents expressing the same meaning with
|
||||
dissimilar wording will return a lower similarity score than two documents
|
||||
that happen to contain the same words while expressing different meanings.
|
||||
|
||||
<Infobox title="Tip: Check out sense2vec" emoji="💡">
|
||||
|
||||
<Image
|
||||
src="/images/sense2vec.jpg"
|
||||
href="https://github.com/explosion/sense2vec"
|
||||
alt="sense2vec Screenshot"
|
||||
/>
|
||||
|
||||
[`sense2vec`](https://github.com/explosion/sense2vec) is a library developed by
|
||||
us that builds on top of spaCy and lets you train and query more interesting and
|
||||
detailed word vectors. It combines noun phrases like "fast food" or "fair game"
|
||||
and includes the part-of-speech tags and entity labels. The library also
|
||||
includes annotation recipes for our annotation tool [Prodigy](https://prodi.gy)
|
||||
that let you evaluate vectors and create terminology lists. For more details,
|
||||
check out [our blog post](https://explosion.ai/blog/sense2vec-reloaded). To
|
||||
explore the semantic similarities across all Reddit comments of 2015 and 2019,
|
||||
see the [interactive demo](https://explosion.ai/demos/sense2vec).
|
||||
|
||||
</Infobox>
|
||||
Reference in New Issue
Block a user