区分良好的英语句子和“word salad”

时间:2015-10-11 17:16:46

标签: nlp stanford-nlp

我正在寻找一个可以从C ++,Python或F#中轻松使用的库,它可以将形式良好的英语句子与“word salad”区分开来。我试过The Stanford Parser,不幸的是,它解析了这个:

Some plants have with done stems animals with exercise that to predict?

没有投诉。我不是在寻找能够处理所有可能的角落情况的非常复杂的东西。我只需要过滤掉明显的废话。

2 个答案:

答案 0 :(得分:2)

以下是我偶然发现的事情: A general-purpose sentence-level nonsense detector,由斯坦福大学的学生Ian Tenney撰写。

Here is the code from the project, undocumented but available on GitHub.

如果您想基于此开发自己的解决方案,我认为您应该注意第3和第34部分中使用的第4组功能,即语言模型;功能和预处理"。

这可能还不够,但我认为获得长度为n的每个子序列的概率得分是一个好的开始。 3克喜欢"植物有","完成","完成茎动物","茎动物用"和#34;预测"看起来很不可能,这可能导致一个“废话”#34;整个句子上的标签。

这种方法的优点是依赖于学习的模型,而不是依赖于一组手工制作的规则,而这些规则是你的另一种选择。很多人都会指向Chapter 8 of NLTK's manual,但我认为开发一种适用于普通英语的自己的无语境语法会有点问题。

答案 1 :(得分:1)

这篇论文很有用,但是对于解决这个问题太深入了。这是作者的basic approach,启发式地:

  1. 基准句启发式:首字母大写, 并以。?!之一结尾(1 feature)。
  2. 字符,单词,标点符号,数字和命名实体的数量(来自Stanford CoreNLP NER标记),以及按文本长度(10 features)归一化的版本。
  3. 词类分布标签:每个Penn树库标签(45 features的(#/#个单词)。
  4. 第一个语音标记的指示器 和文本中的最后一个标记(45x2 = 90 features)。
  5. 语言模型原始分数(s lm = log p(文本)) 和归一化分数(s¯lm= s lm /#个单词)(2 features)。

但是,经过大量搜索之后,github存储库仅包含测试和可视化。原始训练和测试数据不存在。这是他计算这些功能的功能:

(注意:这将pandas数据帧用作df)

def make_basic_features(df):
    """Compute basic features."""

    df['f_nchars'] = df['__TEXT__'].map(len)
    df['f_nwords'] = df['word'].map(len)

    punct_counter = lambda s: sum(1 for c in s
                                  if (not c.isalnum())
                                      and not c in
                                        [" ", "\t"])
    df['f_npunct'] = df['__TEXT__'].map(punct_counter)
    df['f_rpunct'] = df['f_npunct'] / df['f_nchars']

    df['f_ndigit'] = df['__TEXT__'].map(lambda s: sum(1 for c in s
                                  if c.isdigit()))
    df['f_rdigit'] = df['f_ndigit'] / df['f_nchars']

    upper_counter = lambda s: sum(1 for c in s if c.isupper())
    df['f_nupper'] = df['__TEXT__'].map(upper_counter)
    df['f_rupper'] = df['f_nupper'] / df['f_nchars']

    df['f_nner'] = df['ner'].map(lambda ts: sum(1 for t in ts
                                              if t != 'O'))
    df['f_rner'] = df['f_nner'] / df['f_nwords']

    # Check standard sentence pattern:
    # if starts with capital, ends with .?!
    def check_sentence_pattern(s):
        ss = s.strip(r"""`"'""").strip()
        return s[0].isupper() and (s[-1] in '.?!')
    df['f_sentence_pattern'] = df['__TEXT__'].map(check_sentence_pattern)

    # Normalize any LM features
    # by dividing logscore by number of words
    lm_cols = {c:re.sub("_lmscore_", "_lmscore_norm_",c)
               for c in df.columns if c.startswith("f_lmscore")}
    for c,cnew in lm_cols.items():
        df[cnew] = df[c] / df['f_nwords']

    return df

所以我想这是在这种情况下可以使用的功能。对于简约版本:

raw = ["This is is a well-formed sentence","but this ain't a good sent","just a fragment"]
import pandas as pd
df = pd.DataFrame([{"__TEXT__":i, "word": i.split(), 'ner':[]} for i in raw])

解析器似乎想要一个单词列表,并使用Stanford CoreNLP库(使用Java编写)识别命名实体(NER)。您什么也不能传入(空列表[]),该函数会计算其他所有内容。您将获得具有句子所有功能的数据框(如矩阵),然后可以根据给定的规则来决定用什么来称呼“结构良好”。

此外,您不必在这里使用熊猫。词典列表也将起作用。但是原始代码使用的是熊猫。

由于此示例涉及许多步骤,因此我创建了要点,在其中贯穿示例,直到生成完整的句子列表和格式不正确的句子< / strong>

我的要旨: https://gist.github.com/marcmaxson/4ccca7bacc72eb6bb6479caf4081cefb

这将Stanford CoreNLP Java库替换为spacy-一种更新且更易于使用的python库,用于填充缺少的元数据,例如情感,命名实体和用于确定词性的词性如果句子格式正确。这可以在python 3.6下运行,但可以在2.7下运行。所有的库都向后兼容。