【问题标题】:Is it possible to get a natural word after it has been stemmed?词干化后是否有可能得到一个自然词?
【发布时间】:2015-02-10 18:52:49
【问题描述】:

我有一个词play,在词干化之后变成了plai。现在我想再次play。是否可以?我用过 Porter's Stemmer。

【问题讨论】:

    标签: nlp stemming porter-stemmer


    【解决方案1】:

    显然不是。许多不同的词,经过词干后,可以变成plai:包括play和playing。

    在这里试试:http://9ol.es/porter_js_demo.html

    因此,如果给定 plai,它可能来自任何一个词,那么它就不是确定性的。或者你想得到所有可能的词干为plai的词集?

    更新: Qualtagh 提到了一些好主意。

    【讨论】:

    • 是否有可能得到一组可能出现的单词?
    【解决方案2】:

    Stemmer 能够处理人工不存在的单词。您希望它们作为一组所有可能单词的元素返回吗?你怎么知道这个词不存在也不应该被退回?

    作为一个选项:查找所有单词及其形式的字典。为他们每个人找到一个词干。将此投影保存为地图:(词干,所有单词形式的列表)。因此,您将能够获得给定词干的所有单词形式的列表。

    统一更新: 如果您需要所有可能的单词,包括不存在的单词,那么我可以提供这样的算法(未检查,只是一个建议):

    Porter stemming algorithm。我们需要一个颠倒的版本。

    如果直接算法中的规则是(m>1) E ->(删除最后一个E),那么反向规则将是“fork with E”,这意味着我们需要尝试其他方法。例如,在直接算法probate -> probat 中,在反向算法中,我们有两种选择:probat -> { probat, probate }。这些备选方案中的每一个都应单独进一步处理。请注意,这是一个 set 备选方案,因此我们将只处理不同的单词。这样的规则将具有以下形式:A -> { , B, C },这意味着“以三种替代方式替换结尾 A:保持原样、使用 B 和使用 C”。

    Step 5b: (m>1) *L -> { , +L } // Add L if there's L at the end.
    Step 5a: (m>1) -> { , +E }
             (m=1 and not *o) -> { , +E } // *o is a special condition, it's not *O.
    Step 4: (m>1) *S or *T -> { , +ION }
            (m>1) -> { , +AL, +ANCE, +ENCE, ..., +IVE, +IZE }
    Step 3: (m>0) *AL -> { , +IZE }
            (m>0) *IC -> { , +ATE, +ITI, +AL }
            (m>0) -> { , +ATIVE, +FUL, +NESS }
    Step 2: (m>0) *ATE -> { , ATIONAL } // Replace ATE.
            (m>0) *TION -> { , +AL } // Add AL at the end.
            (m>0) *ENCE -> { , ENCI } // Replace ENCE.
            ...
            (m>0) *BLE -> { , BILITI } // Replace BLE.
    Step 1c: (*v*) *I -> { , Y } // Replace I.
    Step 1b: (m=1 and *oE) -> { , +D, delete last E and add ING } // *o is a special condition.
             (*v*c and not (*L or *S or *Z)) -> { , add last consonant +ED, add last consonant + ING }
             *IZE -> { , IZING, +D }
             (*v*BLE) -> { , +D, delete last E and add ING }
             *ATE -> { , ATING, +D }
             (*v*) -> { , +ED, +ING }
             (m>0) *EE -> { , +D }
    Step 1a: *I -> { , +ES }
             *SS -> { , +ES }
             not *S -> { , +S }
    

    直接算法必须选择第一个最长的规则。逆向算法应该使用所有规则。

    示例(直):

    Input: PLAYING
    Step 1a doesn't match.
    PLAYING -> PLAY (Step 1b)
    PLAY -> PLAI (Step 1c)
    m=0, so the steps 2-5 don't match.
    Result: PLAI
    

    反转:

    Input: PLAI
    m=0, so the steps 2-5 are skipped
    Step 1c:
    PLAI -> { PLAI, PLAY }
    Step 1b:
    PLAI -> { PLAI, PLAIED, PLAIING }
    PLAY -> { PLAY, PLAYED, PLAYING }
    Resulting set: { PLAI, PLAIED, PLAIING, PLAY, PLAYED, PLAYING }
    Step 1a:
    PLAI -> { PLAI, PLAIS, PLAIES }
    PLAIED -> { PLAIED, PLAIEDS }
    PLAIING -> { PLAIING, PLAIINGS }
    PLAY -> { PLAY, PLAYS }
    PLAYED -> { PLAYED, PLAYEDS }
    PLAYING -> { PLAYING, PLAYINGS }
    Resulting set: { PLAI, PLAIS, PLAIES, PLAIED, PLAIEDS, PLAIING, PLAIINGS, PLAY, PLAYS, PLAYED, PLAYEDS, PLAYING, PLAYINGS }
    

    我在Michael Tontchev 的链接中检查了所有这些词。他们每个人的结果都是“plai”(请注意,该网站不接受大写输入)。

    【讨论】:

    • 感谢您的回答。我在哪里可以得到这样的字典。我正在用 PHP 编码
    • @eddard.stark,看看herehere。您只需要一个大文本文件,该文件将被处理一次以获得( stem, list of words ) 对,以便将它们存储在任何本地数据库(或Patricia 树或DAWG 等数据结构)中。
    • @eddard.stark,我已经针对所有可能的(包括不存在的)变体的情况更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 2019-02-13
    相关资源
    最近更新 更多