一个句子背景:我有来自自动转录会话的文本数据,我想比较他们的内容的相似性(例如他们在谈论什么)来进行聚类和推荐。我对NLP很新。
数据:我使用的数据可用here。对于所有懒惰的人
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 。这或多或少与基线无关。现在,鉴于缺乏预处理,这可能不会出现重大意外。
解决方案策略:根据this post中的建议,我想执行以下操作(尽可能使用spaCy):1)删除停用词。 2)删除最常用的单词。 3)合并单词对。 4)可能在spaCy之外使用Doc2Vec。
问题:以上看起来像是一个合理的策略吗?如果不是,缺少什么?如果是,通过使用nlp = spacy.load('en_core_web_lg')
中加载的预训练模型,已经在幕后发生了多少?
我似乎无法找到演示这些模型正在做什么或如何配置它的文档。一个quick google search yields nothing甚至是非常整洁,api documentation似乎没有帮助。也许我在寻找错误的地方?
答案 0 :(得分:2)
您可以使用SpaCY和一些正则表达式来完成大部分操作。
因此,您必须看一下SpaCY API documentation。
任何NLP管道中的基本步骤如下:
语言检测(不言而喻,如果您正在使用某些数据集,那么您会知道语言是什么,然后可以根据需要调整管道)。如果您知道一种语言,则必须从SpaCY下载正确的模型。指示为here。在此示例中,使用英语。在命令行中,键入python -m spacy download en
,然后将其导入到预处理脚本中,如下所示:
import spacy
nlp = spacy.load('en')
标记化-这是将文本拆分为单词的过程。仅做text.split()
是不够的(例如there's
被视为一个单词,但实际上是两个单词there
和is
)。因此,这里我们使用分词器。在SpaCy中,您可以执行以下操作:
nlp_doc = nlp(text)
其中text
是您的数据集语料库或数据集中的样本。您可以阅读有关文档实例here
标点删除-由上一步中的方法完成的漂亮的自我解释过程。要删除标点符号,只需键入:
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]
POS标记-词性标记的缩写。这是将文本中的单词标记为与语音的特定部分相对应的过程。例如:
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./.
其中斜杠后的大写代码是标准单词标签。可以找到标签列表here
在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
在SpaCy中,已经通过将文本放入nlp
实例来为您完成。您可以通过以下方式获得每个单词的引理:
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通过删除最常见的单词来创建单词向量。另外,与通常的过程相反,您可能想保留最具体的词,因为您的任务是更好地区分两个文本。我希望这足够清楚:)