AIの作った文章って、途中で切れる時あるから、日本語の文章をいい感じに区切りたい。

# Code from https://qiita.com/wwwcojp/items/3535985007aa4269009c
import functools

このコードは "functools "と呼ばれるライブラリをインポートしています。これは、誰かが何かを作るために使う道具の大きな箱のようなものだと考えてください。

split_punc2 = functools.partial(split_punctuation, punctuations=r".!?")
この行はsplit_punc2というツールを作成しています。これはfunctoolsボックスの中にあるpartialという別のツールを使って作られています。これは、既存のツールをベースにして新しいツールを作成するようなものです。既存のツールはsplit_punctuationで、ピリオド、感嘆符、疑問符などの特定の句読点に基づいて文章を分割するために使用されます。punctuations=r".and!"の部分は、これらの特定の句読点でのみ文章を分割するようにツールに指示しています。

concat_tail_no = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(of)$", remove_former_matched=False)
この行は、concat_tail_noという別のツールを作成しています。これもfunctoolsのパーシャルツールを使って構築されています。この新しいツールは、concatenate_matchingという別のライブラリ(ここでは示していません)内の別のツールに基づいています。このツールは、特定のパターンにマッチする文章を結合するために使われます。この場合、「of」という単語で終わる文を探し、その前の文と結合している。

concat_decimal = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(\d.)$", latter_matching_rule=r"^(\d)(?P<result>.+)$" , remove_former_matched=False , remove_latter_matched=False)
この行は concat_decimal という別のツールを作っています。これも concatenate_matching に基づいていますが、ルールが異なります。このツールは、数字(1、2、3など)で終わる文章を探し、その前後の文章と結合します。former_matching_ruleとlater_matching_ruleの部分が、文のマッチングに使われるルールです。

segmenter = make_pipeline(normalize, split_newline, concat_tail_no, split_punc2, concat_decimal)
この最後の行は、前に作ったすべてのツールを組み合わせて(ツールボックスのように!)、パイプラインを作成しています。パイプラインは、おもちゃを組み立てるための説明書のようなものだと考えてください。パイプラインは、すべてのツールを正しい順序で組み合わせて、テキストをセンテンスに分割します。ここで使用するツールは、normalize、split_newline、concat_tail_no、split_punc2、concat_decimalです。

from ja_sentence_segmenter.common.pipeline import make_pipeline
from ja_sentence_segmenter.concatenate.simple_concatenator import concatenate_matching
from ja_sentence_segmenter.normalize.neologd_normalizer import normalize
from ja_sentence_segmenter.split.simple_splitter import split_newline, split_punctuation

エラーが発生

--------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) <ipython-input-3-d014876a1a64> in <module> ----> 1 from ja_sentence_segmenter.common.pipeline import make_pipeline 2 from ja_sentence_segmenter.concatenate.simple_concatenator import concatenate_matching 3 from ja_sentence_segmenter.normalize.neologd_normalizer import normalize 4 from ja_sentence_segmenter.split.simple_splitter import split_newline, split_punctuation ModuleNotFoundError: No module named 'ja_sentence_segmenter' --------------------------------------------------------------------------- NOTE: If your import is failing due to a missing package, you can manually install dependencies using either !pip or !apt. To view examples of installing some common dependencies, click the "Open Examples" button below. ---------------------------------------------------------------------------

このコードは 'ja_sentence_segmenter' というモジュールからいくつかの関数をインポートしようとしていますが、そのモジュールを見つけることができません。そのため、"ModuleNotFoundError "というエラーメッセージが表示されています。

例えるなら、先生が学校の図書館で本を探そうとしているのに、その本がないようなものです。先生は司書に助けを求めますが、司書はその本は図書館にないと言います。

! pip install ja-sentence-segmenter

このコードは、"pip "というツールを使って、"en-sentence-segmenter "というパッケージをインストールしています。

わかりやすく説明すると、遊ぶために新しいおもちゃが必要で、それを買いにお店に行くとします。この場合、"pip "はお店、"en-sentence-segmenter "は買いたいおもちゃのようなものです。つまり、このコードはお店(pip)におもちゃ(en-sentence-segmenter)を買ってきて、私たちのコンピュータにインストールするように言っているのです。

from ja_sentence_segmenter.common.pipeline import make_pipeline
from ja_sentence_segmenter.concatenate.simple_concatenator import concatenate_matching
from ja_sentence_segmenter.normalize.neologd_normalizer import normalize
from ja_sentence_segmenter.split.simple_splitter import split_newline, split_punctuation

もう一度実行する。

1行目で、en_sentence_segmenterというパッケージのcommon.pipelineモジュールから、make_pipeline関数をインポートしています。

次の行では、concatenate_matching関数をja_sentence_segmenterというパッケージのsimple_concatenatorモジュールからインポートしています。

そして、neologd_normalizer モジュールから normalize 関数を、同じく ja_sentence_segmenter パッケージの simple_splitter モジュールから split_newline と split_punctuation 関数をインポートしています。

make_pipelineはテキストを処理する一連のステップを作成するために、 concatenate_matchingは断片化した日本語文を結合するために、normalizeは日本語文を標準化するために、 split_newlineとsplit_punctuationはテキスト中の改行や句読点の位置に基づいて 文章を分割するために使用される関数で、それぞれがテキスト中の文章を分割するための 異なる側面で役に立っています。

split_punc2 = functools.partial(split_punctuation, punctuations=r"。!?")
concat_tail_te = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(て)$", remove_former_matched=False)
segmenter = make_pipeline(normalize, split_newline, concat_tail_te, split_punc2)

自然言語処理において、文節分割とは、テキストブロック内の文を識別して分離する処理です。これは、文章単位でテキストを分析できるため重要であり、センチメント分析、機械翻訳などのタスクに有用である。

split_punctuation 関数は、ピリオド、疑問符、感嘆符などの句読点に基づいてテキストを分割するために使用されます。split_punc2 = functools.partial(split_punctuation, punctuations=r"...?")
この行は、ライブラリからsplit_punctuationという別の関数を使用するsplit_punc2という新しい関数を作成しています。これは、ピリオド(.)、感嘆符(!)、疑問符(?)など、文の終わり方としてよく使われるものを見たときに、関数がテキストを分割することを意味します。

concatenate_matching関数は、日本語の「て」のような特定の接尾辞を先行する単語に連結する関数である。
concat_tail_te = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(te)$", remove_former_matched=False)
この行は、concat_tail_teという別の新しい関数を作成しています。この関数はconcatenate_matchingを使用しており、特定のパターンにマッチするテキストを結合しています。このパターンはformer_matching_ruleで定義され、r"^(?P<result>.+)(te)$"に設定されています。このパターンは、"te "という文字で終わるあらゆるテキストを探します。

make_pipeline関数は、これらの関数を特定の順序で組み合わせてパイプラインを作成する。パイプラインは、まずテキストを正規化し(例えば、全角文字を半角文字に変換する)、次にテキストを改行に基づいて文に分割し、マッチした接尾辞を連結し、最後にテキストをピリオドや疑問符などの句読点に基づいて文に分割します。
このパイプラインにより、日本語のテキストを自動的に文に分割し、さらに分析することができる。

segmenter = make_pipeline(normalize, split_newline, concat_tail_te, split_punc2) とします。
この行は、これらの関数をすべてまとめて、segmenter という新しい関数を作っています。make_pipeline 関数は、関数が一緒に動作するように順番に並べます。まず正規化から始まり、テキストを作業しやすいように変更します。次に、split_newline で改行文字ごとにテキストを分割し、concat_tail_te で "te" で終わるテキストを結合し、最後に split_punc2 でピリオド、感嘆符、疑問符に基づいてテキストをセンテンスに分割しています。最終的には、長いテキストのブロックを、読みやすく、理解しやすい小さなセンテンスに分割することができる関数となります。

text1 = """
私は「あなたの思いに答えられない。他を当たってほしい。」と言われました!呆然として
その場にたたずむしかありませんでしたそれでも私は信じたい!
"""
print(list(segmenter(text1)))

['私は「あなたの思いに答えられない。他を当たってほしい。」と言われました!', '呆然としてその場にたたずむしかありませんでしたそれでも私は信じたい!']

句読点のピリオドと小数点のピリオドが区別できない問題の場合は、

split_punc2 = functools.partial(split_punctuation, punctuations=r".。 !?")
concat_tail_no = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(の)$", remove_former_matched=False)
concat_decimal = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(\d.)$", latter_matching_rule=r"^(\d)(?P<result>.+)$", remove_former_matched=False, remove_latter_matched=False)
segmenter = make_pipeline(normalize, split_newline, concat_tail_no, split_punc2, concat_decimal)

split_punc2 = functools.partial(split_punctuation, punctuations=r".!?"):この行は、split_punc2という新しい関数を作成します。これは、split_punctuation関数を使用して、.や!などの異なる句読点に基づいて文章を分割しますが、今回は日本語でよく使用される「」のような句読点も含まれています。

concat_tail_no = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(of)$", remove_former_matched=False):この行は、concat_tail_noという別の新しい関数を作ります。これは、concatenate_matching関数を使用して、ofという単語で終わる文を前の文に連結するものです。例えば、「a piece of cake」と「I ate it」という文章があった場合、この関数はそれらを「a piece of cake, I ate it」に結合する。

concat_decimal = functools.partial(concatenate_matching, former_matching_rule=r"^(?P<result>.+)(\d.)$", latter_matching_rule=r"^(\d)(?P<result>.+)$" , remove_former_matched=False, remove_latter_matched=False) とします。この行では、concat_decimal という新しい関数が作成されています。これは、concatenate_matching 関数を使用して、10進数で始まる文を前の文に、または10進数で終わる文を次の文に連結するものです。例えば、「I have 2 apples」と「They are red」という文があった場合、この関数は「I have 2 apples, They are red」に結合する。

segmenter = make_pipeline(normalize, split_newline, concat_tail_no, split_punc2, concat_decimal):この行は、作成した関数(normalize, split_newline, concat_tail_no, split_punc2, concat_decimal)をsegmenterという一つの関数にまとめています。このsegmenter関数は、テキストブロックを受け取り、先ほどsplit_punc2、concat_tail_no、concat_decimal関数で定義したルールに基づいて個々のセンテンスに分割するものです。

つまり、簡単に言うと、このコードは、文が .や !といった一般的な句読点で区切られていない場合でも、テキストブロックを個々の文に分割するのに役立ちます。たとえば、「of」という単語で終わる文や、10進数で始まる文、終わる文があっても、段落を個々の文に分割することができます。

この記事が気に入ったらサポートをしてみませんか?