Пример #1
0
        /// <summary>
        /// Gets the closest synset that is reachable from the current and another synset along the given relations. For example,
        /// given two synsets and the Hypernym relation, this will return the lowest synset that is a hypernym of both synsets. If
        /// the hypernym hierarchy forms a tree, this will be the lowest common ancestor.
        /// </summary>
        /// <param name="synset">Other synset</param>
        /// <param name="relations">Relations to follow</param>
        /// <returns>Closest mutually reachable synset</returns>
        public SynSet GetClosestMutuallyReachableSynset(SynSet synset, IEnumerable <WordNetEngine.SynSetRelation> relations)
        {
            // avoid cycles
            Set <SynSet> synsetsEncountered = new Set <SynSet>();

            synsetsEncountered.Add(this);

            // start search queue
            Queue <SynSet> searchQueue = new Queue <SynSet>();

            searchQueue.Enqueue(this);

            // run search
            SynSet closest = null;

            while (searchQueue.Count > 0 && closest == null)
            {
                SynSet currSynSet = searchQueue.Dequeue();

                /* check for a path between the given synset and the current one. if such a path exists, the current
                 * synset is the closest mutually reachable synset. */
                if (synset.GetShortestPathTo(currSynSet, relations) != null)
                {
                    closest = currSynSet;
                }
                // otherwise, expand the search along the given relations
                else
                {
                    foreach (SynSet relatedSynset in currSynSet.GetRelatedSynSets(relations, false))
                    {
                        if (!synsetsEncountered.Contains(relatedSynset))
                        {
                            searchQueue.Enqueue(relatedSynset);
                            synsetsEncountered.Add(relatedSynset);
                        }
                    }
                }
            }

            return(closest);
        }
        /// <summary>
        /// Gets similarity of two synsets
        /// </summary>
        /// <param name="synset1">First synset</param>
        /// <param name="synset2">Second synset</param>
        /// <param name="strategy">Strategy to use. All strategies named WuPalmer1994* will produce the same result since only two synsets
        /// are available.</param>
        /// <param name="relations">Synset relations to follow when computing similarity (pass null for all relations)</param>
        /// <returns>Similarity</returns>
        public float GetSimilarity(SynSet synset1, SynSet synset2, Strategy strategy, params WordNetEngine.SynSetRelation[] relations)
        {
            if (relations == null)
            {
                relations = Enum.GetValues(typeof(WordNetEngine.SynSetRelation)).Cast <WordNetEngine.SynSetRelation>().ToArray();
            }

            float similarity = 0;

            if (strategy.ToString().StartsWith("WuPalmer1994"))
            {
                // get the LCS along the similarity relations
                SynSet lcs = synset1.GetClosestMutuallyReachableSynset(synset2, relations);
                if (lcs == null)
                {
                    similarity = 0;
                }
                else
                {
                    // get depth of synsets
                    int lcsDepth     = lcs.GetDepth(relations) + 1;
                    int synset1Depth = synset1.GetShortestPathTo(lcs, relations).Count - 1 + lcsDepth;
                    int synset2Depth = synset2.GetShortestPathTo(lcs, relations).Count - 1 + lcsDepth;

                    // get similarity
                    similarity = 2 * lcsDepth / (float)(synset1Depth + synset2Depth);
                }
            }
            else
            {
                throw new NotImplementedException("Unrecognized strategy");
            }

            if (similarity < 0 || similarity > 1)
            {
                throw new Exception("Invalid similarity");
            }

            return(similarity);
        }