nlp - NLP、spaCy:提高文档相似度的策略
问题描述
一句话背景:我有来自自动转录谈话的文本数据,我想比较它们的内容相似度(例如他们在说什么)来进行聚类和推荐。我对 NLP 很陌生。
数据:我使用的数据可在此处获得。对于所有懒惰的人
clone https://github.com/TMorville/transcribed_data
这是将其放入df的代码片段:
import os, json
import pandas as pd
from pandas.io.json import json_normalize
def td_to_df():
path_to_json = '#FILL OUT PATH'
json_files = [pos_json for pos_json in os.listdir(path_to_json) if pos_json.endswith('td.json')]
tddata = pd.DataFrame(columns=['trans', 'confidence'])
for index, js in enumerate(json_files):
with open(os.path.join(path_to_json, js)) as json_file:
json_text = json_normalize(json.load(json_file))
tddata['trans'].loc[index] = str(json_text['trans'][0])
tddata['confidence'].loc[index] = str(json_text['confidence'][0])
return tddata
方法:到目前为止,我只使用 spaCy 包来做“开箱即用”的相似性。我只是将 nlp 模型应用于整个文本语料库,并将其与所有其他语料库进行比较。
def similarity_get():
tddata = td_to_df()
nlp = spacy.load('en_core_web_lg')
baseline = nlp(tddata.trans[0])
for text in tddata.trans:
print (baseline.similarity(nlp(text)))
问题:几乎所有相似性都大于 0.95。这或多或少独立于基线。现在,由于缺乏预处理,这可能不会让人大吃一惊。
解决策略:按照这篇文章中的建议,我想做以下事情(尽可能使用 spaCy): 1)删除停用词。2)删除最常用的词。3) 合并词对。4) 可能在 spaCy 之外使用 Doc2Vec。
问题:以上看起来像是一个合理的策略吗?如果没有,缺少什么?如果是,通过使用加载的预训练模型,这在幕后已经发生了多少nlp = spacy.load('en_core_web_lg')
?
我似乎找不到说明这些模型究竟在做什么或如何配置它的文档。快速的谷歌搜索没有任何结果,甚至非常简洁的api 文档似乎也无济于事。也许我找错地方了?
解决方案
您可以使用SpaCY和一些正则表达式来完成大部分工作。
因此,您必须查看 SpaCY API文档。
任何 NLP 管道中的基本步骤如下:
语言检测(不言自明,如果你正在使用一些数据集,你知道语言是什么,你可以调整你的管道)。当您知道一种语言时,您必须从 SpaCY 下载正确的模型。说明在这里。让我们在这个例子中使用英语。在您的命令行中,只需键入
python -m spacy download en
然后将其导入预处理脚本,如下所示:import spacy nlp = spacy.load('en')
标记化 - 这是将文本拆分为单词的过程。仅仅做是不够的
text.split()
(例如,there's
将被视为一个单词,但实际上是两个单词there
andis
)。所以这里我们使用 Tokenizers。在 SpaCy 中,您可以执行以下操作:nlp_doc = nlp(text)
text
您的数据集语料库或数据集中的样本在哪里。您可以在此处阅读有关文档实例的更多信息
标点符号删除 - 非常不言自明的过程,由上一步中的方法完成。要删除标点符号,只需键入:
import re # removing punctuation tokens text_no_punct = [token.text for token in doc if not token.is_punct] # remove punctuation tokens that are in the word string like 'bye!' -> 'bye' REPLACE_PUNCT = re.compile("(\.)|(\;)|(\:)|(\!)|(\')|(\?)|(\,)|(\")|(\()|(\))|(\[)|(\])") text_no_punct = [REPLACE_PUNCT.sub("", tok.text) for tok in text_no_punct]
词性标注——词性标注的缩写。它是将文本中的单词标记为对应于特定词性的过程。例如:
A/DT Part-Of-Speech/NNP Tagger/NNP is/VBZ a/DT piece/NN of/IN software/NN that/WDT reads/VBZ text/NN in/IN some/DT language/NN and/CC assigns/VBZ parts/NNS of/IN speech/NN to/TO each/DT word/NN ,/, such/JJ as/IN noun/NN ,/, verb/NN ,/, adjective/NN ,/, etc./FW./.
其中斜线后的大写代码是标准单词标签。可以在此处找到标签列表
在 SpaCy 中,这已经通过将文本放入nlp
实例中来完成。您可以通过以下方式获取标签:
for token in doc:
print(token.text, token.tag_)
形态处理:词形还原 - 将单词转换为语言上有效的基本形式的过程,称为引理:
nouns → singular nominative form verbs → infinitive form adjectives → singular, nominative, masculine, indefinitive, positive form
nlp
在 SpaCy 中,通过将文本放入实例中也已经为您完成了。您可以通过以下方式获得每个单词的引理:
for token in doc:
print(token.text, token.lemma_)
删除停用词 - 停用词是不会给句子带来任何新信息或意义的词,可以省略。你猜对了,它也已经通过
nlp
实例为你完成了。要过滤停用词,只需键入:text_without_stopwords = [token.text for token in doc if not token.is_stop] doc = nlp(' '.join(text_without_stopwords))
现在你有了一个干净的数据集。您现在可以使用word2vec或GloVe预训练模型来创建词向量并将您的数据输入到某个模型。或者,您可以使用 TF-IDF 通过删除最常见的词来创建词向量。此外,与通常的过程相反,您可能希望保留最具体的单词,因为您的任务是更好地区分两个文本。我希望这足够清楚:)
推荐阅读
- python - 美丽的汤/硒网页抓取
- python - 从文本文件创建文件夹
- flutter - Firestore中状态更改的问题与switch和flutter true和false
- queue - printf 从各种任务中进行控制台
- javascript - 如何将 JS 生成的按钮附加到 div 而不是正文
- xslt-3.0 - XSLT 3:空节点集的 xsl:analyze-string 不执行 xsl:non-matching-substring
- reactjs - 如何使用 Protractor 为 ReactJS 应用程序测试和编写测试用例?
- flutter - 我想在用户第一次在应用程序中唱歌时设置默认主题,而无需“选择”按钮或复选框
- reactjs - TS2322: Type 'NotRequiredArraySchema
' is not assignable to type 'Ref | Schema I'm solving this problem. I'm using yup for formik validation. Code
- python - How to define a sentence as ,Starting with "uppercase letter" end ending with ".", in a txt file