在不完整句子中用NLTK找主语
我有一份产品列表,想把这些产品分类。它们的描述都是一些不完整的句子,比如:
“固态硬盘外壳”
“硬盘线”
“1TB硬盘”
“500GB硬盘,厂家翻新”
我该如何使用Python和自然语言处理(NLP)来得到像“外壳、线、硬盘、硬盘”这样的输出,或者得到一个树状结构,描述哪个词修饰了哪个词呢?
谢谢大家!
4 个回答
我会先准备一个名词的列表,可以手动列出你想要的所有名词,或者从像这个字典里提取出来。然后,过滤掉其他的词,只保留名词,这样至少能得到“State Drive”、“Drive Cable”或者“Drive”,同时忽略掉第一个标点符号后面的内容。
首先,你需要在你的电脑上安装一个叫做spacy的工具。你可以通过在命令行中输入以下命令来安装:
pip install spacy
安装完成后,你还需要下载一个英语的语言包,输入:
python -m spacy download en
然后,你就可以在你的代码中使用spacy了,记得要导入它:
import spacy
nlp = spacy.load('en')
sent = "INCOMEPLETE SENTENCE HERE"
doc=nlp(sent)
sub_toks = [tok for tok in doc if (tok.dep_ == "ROOT") ]
下面是一些例子:
sent = "Solid State Drive Housing"
doc=nlp(sent)
sub_toks = [tok for tok in doc if (tok.dep_ == "ROOT") ]
输出结果是:[Housing]
sent = "Hard Drive Cable"
doc=nlp(sent)
sub_toks = [tok for tok in doc if (tok.dep_ == "ROOT") ]
输出结果是:[Cable]
sent = "1TB Hard Drive"
doc=nlp(sent)
sub_toks = [tok for tok in doc if (tok.dep_ == "ROOT") ]
输出结果是:[Drive]
sent = "500GB Hard Drive, Refurbished from Manufacturer"
doc=nlp(sent)
sub_toks = [tok for tok in doc if (tok.dep_ == "ROOT") ]
输出结果是:[Drive]
NLP(自然语言处理)技术对于处理这种文本的能力相对较弱。
换句话说:虽然可以构建一个包含NLP过程的解决方案来实现所需的分类器,但增加的复杂性并不一定能在开发速度或分类器的准确性上带来好处。
如果真的想使用NLP技术,最明显的想法是词性标注(POS-tagging),它可以识别名词,但还有其他一些可行的使用方式,比如分块(Chunking)和访问WordNet或其他词汇资源。
相反,基于简单的正则表达式和一些启发式规则(比如NoBugs建议的那些)来解决问题,可能是更合适的方法。当然,这样的解决方案有两个主要风险:
- 可能会对构建规则时考虑的文本部分过拟合。
- 如果引入了太多规则和子规则,解决方案可能会变得混乱和复杂。
对待分析的文本进行一些简单的统计分析(完整文本或很大样本)应该有助于选择一些启发式规则,并避免过拟合的问题。我相信,结合自定义字典,少量的规则应该足以产生一个准确性和速度/资源性能都合适的分类器。
以下是一些想法:
- 统计一部分文本中的所有单词(可能还包括所有的二元组和三元组)。这些信息可以帮助设计分类器,让我们把更多的精力和更严格的规则放在最常见的模式上。
- 手动引入一个简短的字典,将最常用的单词与:
- 它们的词性功能(这里主要是二元问题:即名词与修饰词和其他非名词的区别)
- 它们的同义词根(如果适用)
- 它们的类别(如果适用)
- 如果这个模式在大多数输入文本中成立,可以考虑使用文本结束前的最后一个单词或第一个逗号前的单词作为主要的分类关键字。如果模式不成立,就给第一个和最后一个单词更多的权重。
- 考虑进行第一次处理,将文本中最常见的二元组替换为一个单词(甚至是一个人工的代码词),这个词会在字典中。
- 还可以考虑将最常见的拼写错误或同义词替换为它们对应的同义词根。增加输入的规律性有助于提高准确性,并且让一些规则/字典中的条目获得更大的准确性回报。
- 对于字典中找不到的单词,假设与数字混合或前面有数字的单词是修饰词,而不是名词。
- 考虑采用两级分类,对于那些无法合理分配类别的输入,放入“手动处理”堆中,以便进行额外审查,从而增加规则和/或字典条目。经过几次迭代后,分类器应该需要越来越少的改进和调整。
- 寻找一些不明显的特征。例如,有些语料库是由多种来源混合而成,但某些来源可能包含特定的规律,有助于识别来源和/或作为分类提示。例如,有些来源可能只包含大写文本(或通常超过50个字符的文本,或结尾截断的单词等)。
我担心这个回答没有提供Python/NLTK的代码片段作为解决方案的入门,但坦白说,这种简单的基于NLP的NLP方法可能最多也只是令人失望。此外,我们应该有一个更大的输入文本样本集,以指导选择合理的方法,包括那些基于NLP或更广泛的NLP技术的方法。