说法表的 scan 加 bare=True:只按词认、不看上下文(构成、建议计划、业务状态、「相当」的比法、「未见异常」的主语这些只对整句话成立的规矩都不用),给认叫法(度量的叫法、因子名)里夹带的判断词用——叫法是一个名字不是一句话,「主要来自华东的销售额」照样认出来源;缺省照旧按整句的规矩。原因只是指代的那条注释改准。测试:几个叫法按词认、按整句不认

This commit is contained in:
ThearchyHelios
2026-10-21 17:10:43 +08:00
parent cf1cc568d6
commit 2d616d01e8
2 changed files with 18 additions and 5 deletions
+9 -5
View File
@@ -395,10 +395,13 @@ def _count(word: str) -> int | None:
return (_CN_DIGITS.get(tens, 0) if tens else 1) * 10 + (_CN_DIGITS.get(ones, 0) if ones else 0)
def scan(text: str, *, version: int | None = None) -> list[Hit]:
def scan(text: str, *, version: int | None = None, bare: bool = False) -> list[Hit]:
"""一句话里的判断词(text 是写作者自己写的字,别的片段已经涂成 \\x00)。同一处有几种读法时取最靠前、最长的:
「超出正常范围」是异常不是正常,「没有明显的上升或下降趋势」是无趋势不是趋势。不核的写法(_counts)连同和它重叠的
读法一起跳过。"""
读法一起跳过。
bare=True 只按词认、不看上下文:构成、建议计划、业务状态、「相当」的比法、「未见异常」的主语这些只对整句话成立的
规矩都不用——认叫法(度量的叫法、因子名)里夹带的判断词时用它,叫法是一个名字,不是一句话。"""
lex = lexicon(version)
found: list[tuple[int, int, int, Claim]] = []
for order, claim in enumerate(lex.claims):
@@ -413,7 +416,7 @@ def scan(text: str, *, version: int | None = None) -> list[Hit]:
continue
taken = end
left, right = _clause(text, start, end)
if not _counts(lex, claim, text, start, end, left, right):
if not bare and not _counts(lex, claim, text, start, end, left, right):
continue
before = text[left:start]
key, negated = claim.key, False
@@ -423,7 +426,8 @@ def scan(text: str, *, version: int | None = None) -> list[Hit]:
continue
key = claim.flip
word = text[start:end]
if key == "normal" and (claim.subject or (negated and "异" in word)) and not lex.subject.search(text[:right]):
if not bare and key == "normal" and (claim.subject or (negated and "异" in word)) \
and not lex.subject.search(text[:right]):
continue # 「未见异常」「没有出现异动」:主语不是指标、波动的(运行平稳、系统正常)不核
direction = _direction(lex, word, text[end:right], text[left:right])
run = claim.run and not negated
@@ -848,7 +852,7 @@ def _cause(sentence: Sentence, hit: Hit, left: int, right: int) -> str:
return names[left + by[-1]:hit.start] if by else names[left:hit.start]
#: 原因只是指代(「以上是下降的主要原因」「原因如下:」后面的列表各自核):这一句不核
#: 原因只是指代(「以上是下降的主要原因」「下降的主要原因:」,列出原因的那几句各自核):这一句不核
_POINTER = re.compile(r"(?:这|那|此|其|以上|上述|前述|如下|以下|下列)(?:些|个|几个|几点|两点|方面|原因|因素)?")
_FILLING = re.compile(r"[\x00\s\W_]|的|都|也|就|主要|正是|便是|即")
@@ -143,3 +143,12 @@ def test_the_sample_table_is_not_shorter_than_the_review():
def test_runs_carry_the_number_of_periods_they_claim(text, count):
[run] = [h for h in ac.scan(text) if h.run]
assert run.count == count
@pytest.mark.parametrize("label, claims", [("主要来自华东的销售额", ["source"]), ("集中在线上的订单", ["source"]),
("建议持续降低的退款率", ["trend"]), ("部分订单异常", ["anomaly"]),
("销售额", [])])
def test_bare_scanning_finds_judgement_words_in_a_name(label, claims):
"""认叫法里夹带的判断词(bare=True)只按词认:叫法是一个名字不是一句话,构成、建议计划、业务状态这些整句话的规矩不用。"""
assert [h.claim for h in ac.scan(label, bare=True)] == claims
assert ac.scan(label) == []