We asked ourselves questions like:
- Is there a structure between Verbs?
- Do Verbs have arguments?
- What's the relationship between buying and purchasing? Sending an receiving?
I figure that it could be useful to document what was the thinking process and the types of resources we created as we were approaching the problem in case anyone runs into this too :)
The underlying motivation was to enable this to be built.
Here is a presentation that I gave at a local conference.
Motivation
The main problem we were trying to solve with the hierarchy was twofold:- ambiguity: one verb having two distinct meanings that fits it
- synonyms: one meaning having two distinct verbs that describes it
An example of synonyms is Buy and Purchase: they both mean the exact same thing. We pick one and we make it clear on the documentation that one refers to the other.
An example of ambiguity is "Receive": does it mean "ownership" is being transferred (e.g. receive an award/gift)? does it mean that the object has moved (e.g. receiving a package)? or does it mean assignment (e.g. i received a task)?
We solve ambiguity by fixating a meaning, and using more verbs for the other meanings under different hierarchies. For example: Receive means getting an object that was moved from one place to another; Taking is for when the object has been given to you and is now yours; Accepting/Rejecting is what you do when a task is assigned to you.
Additionally, a hierarchy benefits us in three ways:
- consistency: actions look a lot like the other subtrees in schema.org
- generalization: actions can be processed/consumed more easily by machines, which can "understand" just at the granularity level it needs to
- inheritance of properties: sub-actions inherit properties from their parents.
Process
Using dictionaries, wordnet and framenet, we built the following tables (full raw tables):- A table of synonyms
- A table of antonyms
- Usage samples
- Potential omissions
- Existing developers/companies's usage
We applied (2) and tried to add antonyms to the verbs that were missing them.
We started clustering the tree applying (1) and (3) and making sure that every single synonym had a specific place in the tree, such that the ancestor path would make it clear what specific meaning we fixed to the verb.
We clustered verbs that were related (e.g. verbs for interactions between humans, communications, production of creative work, consumption, etc) and shared characteristics (e.g. semantic roles, types of objects). From these clusters, we picked generic representatives as parents and moved specializations to the bottom.
Design and Principles
The clustering algorithm and leader election wasn't easy to set on. We iterated on it a few times before we got to something that we felt comfortable with. Here is what we eventually converged to:- All actions in the actions hierarchy are self sufficient actions: useful, meaningful and instantiable.
- Actions are clustered in sub trees of their synonyms, gaining specialization as you go down. The list of ancestors should be a list of synonyms of the action, increasing generality/broadness as it goes up. All actions derive from more generic actions in either manner, purpose or object it deals with.
- Actions are object-agnostic: there are *no* Nouns in their definitions (e.g. WatchMovieAction vs WatchDogAction is represented simply as WatchAction.object = movie or dog). This is done for scalability purposes: we don't want the tree to evolve into an explosion of X-Y-Actions, where X is a verb and Y is a noun.
- When a verb is ambiguous, we fix its meaning to a specific facet and we make it clear. When other facets needs to be represented, we pick one of its synonyms and put it on another part of the tree.
- When there are synonyms that mean the exact same thing, we pick a representative and we merge the meanings (e.g. Purchase and Buy). We understand that that may create dissatisfaction because we didn't pick the name you use in your product, but we are ok with that because we can't have synonyms in the tree (i.e. two verbs that means the exact same thing).
- While adding more actions, an action should have as a parent the most specific existing synonym that can be found. If none is found, a new sub-tree is created. When a new sub-tree is created, we looked at table (4) to find a potential cluster or we re-structure the existing tree with better leaders.
- Actions may have reciprocals.
- Actions may have antagonyms.
- Actions that have a temporal-relationship (i.e. one happens *after* the other) are *not* always synonyms (e.g. WriteAction normally gets followed by ShareAction, but one *is-not* a synonym of the other).
- The tree takes into consideration existing online activity and lingo used on the web. It is optimized for modelling user's online actions rather than written/formal/poetic english.
On Arguments
- We get all the semantic roles from wordnet and framenet while creating properties/roles/slots/arguments for verbs. Here is an example.
- We merged the semantic roles "patient" and "theme" into "object" because we thought the distinction between objects that go over a change and objects that don't isn't an important one.
- Sub actions share the properties from their ancestors, so it is important to use in the structure properties that apply to their children. Sharing properties can be used to make a case for creating structure between actions.