Python 如何使用NLTK正则表达式模式用向上/向下指示器注释金融新闻?
我正在复制本文中描述的算法: 在最后一页中,它使用以下示例描述了如何提取标记为“NP JJ”的语法中定义的叶:营业利润率为8.3%,而去年为11.8% 我希望看到一个标签为“NP JJ”的叶子,但我没有。我对其原因(对正则表达式来说相对较新)感到非常惊讶Python 如何使用NLTK正则表达式模式用向上/向下指示器注释金融新闻?,python,regex,nlp,nltk,Python,Regex,Nlp,Nltk,我正在复制本文中描述的算法: 在最后一页中,它使用以下示例描述了如何提取标记为“NP JJ”的语法中定义的叶:营业利润率为8.3%,而去年为11.8% 我希望看到一个标签为“NP JJ”的叶子,但我没有。我对其原因(对正则表达式来说相对较新)感到非常惊讶 def split_句子(句子作为字符串): ''函数将句子拆分为单词列表 ''' 单词=单词标记化(句子作为字符串) 回话 def词性标签(句子列表): words=nltk.pos标签(句子列表) 回话 def get_regex(句子、语
def split_句子(句子作为字符串):
''函数将句子拆分为单词列表
'''
单词=单词标记化(句子作为字符串)
回话
def词性标签(句子列表):
words=nltk.pos标签(句子列表)
回话
def get_regex(句子、语法):
句子=词性标注(分句(句子));
cp=nltk.RegexpParser(语法)
结果=cp.parse(句子)
返回结果
example_Session=“营业利润率为8.3%,而去年同期为11.8%。”
语法=“JJ:{ ∗}
vb:{}
NP:{()∗}
npp:{}
RB:{}
CD:{}
NP JJ:{+(<(>)。∗ > ∗ ) ∗ (∗ < RB>∗ < JJ>∗ < NP | NP P>)∗ < RB>∗()∗ < V B>()∗ < NP | NP P>∗ < CD>∗ < .∗ > ∗ < CD>∗| < NP | NP P><。∗ > ∗ < V B>”
语法=语法。替换('∗','*')
tree=get\u regex(例句,语法)
打印(树)
首先,请参见
让我们看看这个句子的词性标签是什么:
from nltk import word_tokenize, pos_tag
text = "Operating profit margin was 8.3%, compared to 11.8% a year earlier."
pos_tag(word_tokenize(text))
[out]:
[('Operating', 'NN'),
('profit', 'NN'),
('margin', 'NN'),
('was', 'VBD'),
('8.3', 'CD'),
('%', 'NN'),
(',', ','),
('compared', 'VBN'),
('to', 'TO'),
('11.8', 'CD'),
('%', 'NN'),
('a', 'DT'),
('year', 'NN'),
('earlier', 'RBR'),
('.', '.')]
Tree('S', [('Operating', 'NN'), ('profit', 'NN'), ('margin', 'NN'), ('was', 'VBD'),
Tree('PERCENT', [('8.3', 'CD'), ('%', 'NN')]),
(',', ','), ('compared', 'VBN'), ('to', 'TO'),
Tree('PERCENT', [('11.8', 'CD'), ('%', 'NN')]),
('a', 'DT'), ('year', 'NN'), ('earlier', 'RBR'), ('.', '.')])
Tree('S', [('Operating', 'NN'), ('profit', 'NN'), ('margin', 'NN'), ('was', 'VBD'),
Tree('P2P', [
Tree('PERCENT', [('8.3', 'CD'), ('%', 'NN')]),
(',', ','), ('compared', 'VBN'), ('to', 'TO'),
Tree('PERCENT', [('11.8', 'CD'), ('%', 'NN')])]
),
('a', 'DT'), ('year', 'NN'), ('earlier', 'RBR'), ('.', '.')]
)
(S
Operating/NN
profit/NN
margin/NN
was/VBD
(P2P
(PERCENT 8.3/CD %/NN)
,/,
compared/VBN
to/TO
(PERCENT 11.8/CD %/NN))
a/DT
year/NN
earlier/RBR
./.)
(P2P
(PERCENT 8.3/CD %/NN)
,/,
compared/VBN
to/TO
(PERCENT 11.8/CD %/NN)
a/DT
year/NN
earlier/RBR)
首先,在任何标记中都没有JJ
那句话中的任何位置都没有JJ
标记
让我们回到报纸上
尽管如此,思考一下,npjj
并不是最终目标;最终目标是基于一些启发产生UP
或DOWN
标签。
让我们重新表述以下步骤:
向上
/向下
,使用一些启发式
2c.用(2b)中标识的向上
/向下
标记句子CD NN
from
('8.3', 'CD'), ('%', 'NN')
('11.8', 'CD'), ('%', 'NN')
('8.3', 'CD'),
('%', 'NN'),
(',', ','),
('compared', 'VBN'),
('to', 'TO'),
('11.8', 'CD'),
('%', 'NN'),
让我们试着在语法中抓住它
patterns = """
PERCENT: {<CD><NN>}
"""
PChunker = RegexpParser(patterns)
PChunker.parse(pos_tag(word_tokenize(text)))
现在,我们如何得到这个:
是一个好模式,所以让我们尝试对其进行编码
我们知道,与
相比,具有标签VBN to
from
('8.3', 'CD'), ('%', 'NN')
('11.8', 'CD'), ('%', 'NN')
('8.3', 'CD'),
('%', 'NN'),
(',', ','),
('compared', 'VBN'),
('to', 'TO'),
('11.8', 'CD'),
('%', 'NN'),
这个怎么样:
patterns = """
PERCENT: {<CD><NN>}
P2P: {<PERCENT><.*>?<VB.*><TO><PERCENT>}
"""
PChunker = RegexpParser(patterns)
PChunker.parse(pos_tag(word_tokenize(text)))
但是,这种模式可以是任意数字。我们需要一个信号来指示性能指标
由于我不是金融领域的领域专家,简单地利用营业利润率的存在可能是一个好信号,即
from nltk import word_tokenize, pos_tag, RegexpParser
patterns = """
PERCENT: {<CD><NN>}
P2P: {<PERCENT><.*>?<VB.*><TO><PERCENT>}
"""
PChunker = RegexpParser(patterns)
text = "Operating profit margin was 8.3%, compared to 11.8% a year earlier."
indicators = ['operating profit margin']
for i in indicators:
if i in text.lower():
print(PChunker.parse(pos_tag(word_tokenize(text))))
现在我们如何使上升
/下降
?
2b.使用提取的数值,使用一些启发式方法确定上/下方向性
仅从例句中,除了“早”之外,没有其他任何东西告诉我们数字的先行性
因此,让我们假设一下,如果我们有模式百分比VBN到之前的百分比
,我们说第二个百分比是一个旧的数字
import nltk
from nltk import word_tokenize, pos_tag, RegexpParser
patterns = """
PERCENT: {<CD><NN>}
P2P: {<PERCENT><.*>?<VB.*><TO><PERCENT><.*>*<RBR>}
"""
def traverse_tree(tree, label=None):
# print("tree:", tree)
for subtree in tree:
if type(subtree) == nltk.tree.Tree and subtree.label() == label:
yield subtree
PChunker = RegexpParser(patterns)
parsed_text = PChunker.parse(pos_tag(word_tokenize(text)))
for p2p in traverse_tree(parsed_text, 'P2P'):
print(p2p)
和向上
/向下
标签?
导入nltk
从nltk导入单词标记化、pos标记、RegexpParser
“模式=”“”
百分比:{}
P2P:{?*}
"""
PChunker=RegexpParser(模式)
def遍历树(树,标签=无):
#打印(“树:”,树)
对于树中的子树:
如果类型(子树)==nltk.tree.tree和subtree.label()==label:
收益子树
def labelme(文本):
parsed_text=PChunker.parse(pos_标记(word_tokenize(text)))
对于traverse_树中的p2p(已解析的_文本“p2p”):
#检查子树是否以“早”结尾。
如果p2p.leaves()[-1]==('previous','RBR'):
#检查哪个百分比更大。
p2p.leaves()中num的百分比=[float(num[0]),如果num[1]=='CD']
#检查我们的模式是否只有两个数字。
断言长度(百分比)=2
如果百分比[0]>百分比[1]:
返回“向下”
其他:
返回“向上”
text=“营业利润率为8.3%,而去年同期为11.8%。”
labelme(文本)
现在问题开始了。。。
**您想编写这么多规则并使用上面的labelme()
捕捉它们吗**
您编写的模式是否万无一失?
例如,是否会出现这样一种情况,即使用指标和“更早”比较百分比的模式不会如预期的那样“向上”或“向下”
为什么我们要在人工智能时代写规则?
你是否已经有了人工标注的数据,其中有句子及其相应的上/下标签?如果是这样,让我建议一些类似或奇怪的纸张,但让我们试着浏览一下=)感谢Alvas的反馈,真的很有帮助。不确定是谁否决了你的答案,我认为这是非常直观的。