Skip to content

Commit

Permalink
Merge pull request #131 from tmu-nlp/megumi
Browse files Browse the repository at this point in the history
chapter05
  • Loading branch information
kiyama-hajime authored Jun 24, 2024
2 parents 5ef0277 + 91f3335 commit ad82b2a
Show file tree
Hide file tree
Showing 5 changed files with 634 additions and 1 deletion.
3 changes: 2 additions & 1 deletion megumi/chapter05/knock41.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ def __init__(self, line):

for chunk in sentences[2].chunks:
chunk_str = "".join([morph.surface for morph in chunk.morphs])
print(f"文節の文字列:{chunk_str}\n係り先の文節番号:{chunk.dst}\n")
print(f"文節の文字列:{chunk_str}\n係り先の文節番号:{chunk.dst}\n")

110 changes: 110 additions & 0 deletions megumi/chapter05/knock48.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#48.名詞から根へのパスの抽出
"""
文中のすべての名詞を含む文節に対し,その文節から構文木の根に至るパスを抽出せよ.
ただし,構文木上のパスは以下の仕様を満たすものとする.
・各文節は(表層形の)形態素列で表現する
・パスの開始文節から終了文節に至るまで,各文節の表現を” -> “で連結する
構文木:係り受け解析結果を木構造で表したもの。
"""
class Sentence:
def __init__(self, chunks):
self.chunks = chunks
for i, chunk in enumerate(self.chunks):
if chunk.dst not in [None, -1]:
self.chunks[chunk.dst].srcs.append(i)

class Chunk:
def __init__(self, morphs, dst, chunk_id):
self.morphs = morphs
self.dst = dst
self.srcs = []
self.chunk_id = chunk_id

class Morph:
def __init__(self, line):
surface, other = line.split("\t")
other = other.split(",")
self.surface = surface
self.base = other[6]
self.pos = other[0]
self.pos1 = other[1]

sentences = [] # 文リスト
chunks = [] # 節リスト
morphs = [] # 形態素リスト
chunk_id = 0 # 文節番号

with open("./ai.ja.txt.parsed") as f:
for line in f:
if line[0] == "*":
if morphs:
chunks.append(Chunk(morphs, dst, chunk_id))
chunk_id += 1
morphs = []
dst = int(line.split()[2].replace("D", ""))
elif line != "EOS\n":
morphs.append(Morph(line))
else:
chunks.append(Chunk(morphs, dst, chunk_id))
sentences.append(Sentence(chunks))
morphs = []
chunks = []
dst = None
chunk_id = 0

# 各文の文節で反復させ、文節内に名詞が含まれていれば処理を行う
sentence = sentences[2]
with open("./result48.txt", "w") as f:
for chunk in sentence.chunks:
for morph in chunk.morphs:
if "名詞" in morph.pos:
# pathで、名詞を含む文節内の単語を連結させる。
path = ["".join(morph.surface for morph in chunk.morphs if morph.pos != "記号")]
# 文節の係り先がなくなるまで、係り先文節の形態素列(表層形の)をpathに追加していく。
while chunk.dst != -1:
path.append("".join(morph.surface for morph in sentence.chunks[chunk.dst].morphs if morph.pos != "記号"))
chunk = sentence.chunks[chunk.dst]
# path内の要素を->で連結させて出力する。
f.write("->".join(path) + "\n")


"""
人工知能->語->研究分野とも->される
される
じんこうちのう->語->研究分野とも->される
される
AI->エーアイとは->語->研究分野とも->される
エーアイとは->語->研究分野とも->される
計算->という->道具を->用いて->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
概念と->道具を->用いて->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
コンピュータ->という->道具を->用いて->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
道具を->用いて->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
知能を->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
計算機科学->の->一分野を->指す->語->研究分野とも->される
される
される
一分野を->指す->語->研究分野とも->される
される
語->研究分野とも->される
言語の->推論->問題解決などの->知的行動を->代わって->行わせる->技術または->研究分野とも->される
理解や->推論->問題解決などの->知的行動を->代わって->行わせる->技術または->研究分野とも->される
推論->問題解決などの->知的行動を->代わって->行わせる->技術または->研究分野とも->される
問題解決などの->知的行動を->代わって->行わせる->技術または->研究分野とも->される
される
知的行動を->代わって->行わせる->技術または->研究分野とも->される
される
人間に->代わって->行わせる->技術または->研究分野とも->される
コンピューターに->行わせる->技術または->研究分野とも->される
技術または->研究分野とも->される
計算機->コンピュータによる->情報処理システムの->実現に関する->研究分野とも->される
される
コンピュータによる->情報処理システムの->実現に関する->研究分野とも->される
知的な->情報処理システムの->実現に関する->研究分野とも->される
情報処理システムの->実現に関する->研究分野とも->される
される
設計や->実現に関する->研究分野とも->される
実現に関する->研究分野とも->される
研究分野とも->される
"""
106 changes: 106 additions & 0 deletions megumi/chapter05/knock49.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#49.名詞間の係り受けパスの抽出
"""
文中のすべての名詞句のペアを結ぶ最短係り受けパスを抽出せよ.
ただし,名詞句ペアの文節番号がiとj(i<j)のとき,係り受けパスは以下の仕様を満たすものとする.
問題48と同様に,パスは開始文節から終了文節に至るまでの各文節の表現(表層形の形態素列)を” -> “で連結して表現する
文節iとjに含まれる名詞句はそれぞれ,XとYに置換する
また,係り受けパスの形状は,以下の2通りが考えられる.
文節iから構文木の根に至る経路上に文節jが存在する場合
 : 文節iから文節jのパスを表示
上記以外で,文節iと文節jから構文木の根に至る経路上で共通の文節kで交わる場合
 : 文節iから文節kに至る直前のパスと文節jから文節kに至る直前までのパス,文節kの内容を” | “で連結して表示
"""
class Sentence:
def __init__(self, chunks):
self.chunks = chunks
for i, chunk in enumerate(self.chunks):
if chunk.dst not in [None, -1]:
self.chunks[chunk.dst].srcs.append(i)

class Chunk:
def __init__(self, morphs, dst, chunk_id):
self.morphs = morphs
self.dst = dst
self.srcs = []
self.chunk_id = chunk_id

class Morph:
def __init__(self, line):
surface, other = line.split("\t")
other = other.split(",")
self.surface = surface
self.base = other[6]
self.pos = other[0]
self.pos1 = other[1]

sentences = [] #文リスト
chunks = [] #節リスト
morphs = [] #形態素リスト
chunk_id = 0 #文節番号

with open("./ai.ja.txt.parsed") as f:
for line in f:
if line[0] == "*":
if morphs:
chunks.append(Chunk(morphs, dst, chunk_id))
chunk_id += 1
morphs = []
dst = int(line.split()[2].replace("D", ""))
elif line != "EOS\n":
morphs.append(Morph(line))
else:
chunks.append(Chunk(morphs, dst, chunk_id))
sentences.append(Sentence(chunks))

morphs = []
chunks = []
dst = None
chunk_id = 0

from itertools import combinations
import re

sentence = sentences[2]
nouns = []

with open("./result49.txt", "w") as f:
# 文節を反復させ、名詞を含む文節のインデックス番号をnounsに格納する。
for i, chunk in enumerate(sentence.chunks):
if [morph for morph in chunk.morphs if morph.pos == "名詞"]:
nouns.append(i)

# 名詞句ペアの文節番号i、jを反復させる。
for i, j in combinations(nouns, 2):
path_I = []
path_J = []

# 文節iの構文木根に至る経路上に文節jが存在する場合とそれ以外で条件分岐を行う
while i != j:
if i < j: # 文節iの構文木経路上に文節jが存在する場合
path_I.append(i)
i = sentence.chunks[i].dst
else: # 文節iの構文木経路上に文節jがない場合
path_J.append(j)
j = sentence.chunks[j].dst

if len(path_J) == 0: # 文節Iの構文木上に文節Jが存在する場合
# 文節iとjに含まれる名詞句をXとYに置換する。
X = "X" + "".join([morph.surface for morph in sentence.chunks[path_I[0]].morphs if morph.pos != "名詞" and morph.pos != "記号"])
Y = "Y" + "".join([morph.surface for morph in sentence.chunks[i].morphs if morph.pos != "名詞" and morph.pos != "記号"])
chunk_X = re.sub("X+", "X", X)
chunk_Y = re.sub("Y+", "Y", Y)
# 残りは、文節iと文節jの構文木経路の間のパスを取得し、連結させて出力する。
path_ItoJ = [chunk_X] + ["".join(morph.surface for n in path_I[1:] for morph in sentence.chunks[n].morphs)] + [chunk_Y]
f.write(" -> ".join(path_ItoJ) + "\n")
else: # 文節Iの構文木上に文節Jが存在しない場合
X = "X" + "".join([morph.surface for morph in sentence.chunks[path_I[0]].morphs if morph.pos != "名詞" and morph.pos != "記号"])
Y = "Y" + "".join([morph.surface for morph in sentence.chunks[path_J[0]].morphs if morph.pos != "名詞" and morph.pos != "記号"])
chunk_X = re.sub("X+", "X", X)
chunk_Y = re.sub("Y+", "Y", Y)
chunk_k = "".join([morph.surface for morph in sentence.chunks[i].morphs if morph.pos != "記号"])
path_X = [chunk_X] + ["".join(morph.surface for n in path_I[1:] for morph in sentence.chunks[n].morphs if morph.pos != "記号")]
path_Y = [chunk_Y] + ["".join(morph.surface for n in path_J[1:] for morph in sentence.chunks[n].morphs if morph.pos != "記号")]
f.write(" | ".join(["->".join(path_X), "->".join(path_Y), chunk_k]) + "\n")

38 changes: 38 additions & 0 deletions megumi/chapter05/result48.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
人工知能->語->研究分野とも->される
される
じんこうちのう->語->研究分野とも->される
される
AI->エーアイとは->語->研究分野とも->される
エーアイとは->語->研究分野とも->される
計算->という->道具を->用いて->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
概念と->道具を->用いて->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
コンピュータ->という->道具を->用いて->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
道具を->用いて->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
知能を->研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
研究する->計算機科学->の->一分野を->指す->語->研究分野とも->される
計算機科学->の->一分野を->指す->語->研究分野とも->される
される
される
一分野を->指す->語->研究分野とも->される
される
語->研究分野とも->される
言語の->推論->問題解決などの->知的行動を->代わって->行わせる->技術または->研究分野とも->される
理解や->推論->問題解決などの->知的行動を->代わって->行わせる->技術または->研究分野とも->される
推論->問題解決などの->知的行動を->代わって->行わせる->技術または->研究分野とも->される
問題解決などの->知的行動を->代わって->行わせる->技術または->研究分野とも->される
される
知的行動を->代わって->行わせる->技術または->研究分野とも->される
される
人間に->代わって->行わせる->技術または->研究分野とも->される
コンピューターに->行わせる->技術または->研究分野とも->される
技術または->研究分野とも->される
計算機->コンピュータによる->情報処理システムの->実現に関する->研究分野とも->される
される
コンピュータによる->情報処理システムの->実現に関する->研究分野とも->される
知的な->情報処理システムの->実現に関する->研究分野とも->される
情報処理システムの->実現に関する->研究分野とも->される
される
設計や->実現に関する->研究分野とも->される
実現に関する->研究分野とも->される
研究分野とも->される
される
Loading

0 comments on commit ad82b2a

Please sign in to comment.