著者 | フロリアン・ジューン 編纂者:岳陽 RAGシステムでは、ドキュメントからの情報抽出は避けられません。ソースファイルからコンテンツを効果的に抽出することは、最終出力の品質を向上させる上で非常に重要です。 このプロセスの重要性を過小評価しないでください。RAGシステムを使用する場合、ドキュメント解析中の情報抽出が不十分だと、PDFファイルに含まれる情報の理解と活用が制限されます。 RAG システムにおける解析プロセスの場所を図 1 に示します。 図1: RAGシステムにおける解析プロセスの位置。画像は著者による。 現実の業務シナリオでは、非構造化データは構造化データよりもはるかに多く存在します。しかし、この膨大なデータを解析できなければ、その莫大な価値は活用されず、特にPDF文書はその顕著な例です。 PDF文書は非構造化データの大部分を占めています。PDF文書を効果的に扱うことは、他の種類の非構造化文書の管理にも非常に役立ちます。 この記事では主に PDF ドキュメントを解析する方法を紹介します。これには、PDF ドキュメントを効果的に解析する方法や、できるだけ多くの有用な情報を抽出する方法に関するアルゴリズムや提案などが含まれますが、これらに限定されません。 01 PDF解析の課題PDF ドキュメントは非構造化ドキュメントの代表的な形式ですが、PDF ドキュメントから情報を抽出するのは非常に困難なプロセスです。 PDFをデータ形式として説明するよりも、印刷指示の集合体として説明する方が正確です。PDFファイルは、PDFリーダーやプリンターに、画面や紙面上で様々な記号やテキストをどのように配置して表示するかを指示する一連の指示で構成されています。これは、図2に示すように、 図2: HTMLとPDF。画像は著者による。 PDF文書の解析における課題は、ページ全体のレイアウトを正確に抽出し、すべてのコンテンツ(表、見出し、テキスト段落、画像など)をテキストに変換することです。このプロセスでは、テキスト抽出の不正確さ、画像認識の不正確さ、表内の行と列の関係に関する混乱といった問題が発生する可能性があります。 02 PDF文書を解析する方法一般に、PDF ドキュメントを解析する方法は 3 つあり、それぞれに長所と短所があり、さまざまなシナリオに適しています。
2.1 ルールベースのアプローチ pypdf[1]は、この手法の最も代表的なツールの一つです。広く使用されているルールベースのPDF解析ツールであり、LangChain[2]やLlamaIndex[3]などのライブラリでは、PDFファイルの解析における標準的な手法として使用されています。 以下は、pypdfを用いて論文「Attention Is All You Need」[4]の6ページ目を解析する例です。ページは図3に示されています。 図3:「Attention Is All You Need」論文6ページ 具体的なコードは以下のとおりです。 PyPDF2をインポートする
ファイル名 = "/Users/Florian/Downloads/1706.03762.pdf"pdf_file = open(ファイル名, 'rb')
リーダー = PyPDF2.PdfReader(pdf_file)
ページ番号 = 5
ページ = reader.pages[ページ番号]
テキスト = page.extract_text()
print('--------------------------------------------------')
印刷(テキスト)
pdf_file.close() コードの実行結果は次のとおりです (簡潔にするため、残りは省略します)。 (py) フロリアン:~ フロリアン$ pip リスト | grep pypdf pypdf 3.17.4 pypdfium2 4.26.0 (py) Florian:~ Florian$ python /Users/Florian/Downloads/pypdf_test.py-------------------------------------------------- 表1: 最大パス長、レイヤーごとの複雑さ、および最小連続操作数 異なるレイヤータイプについて。nはシーケンス長、dは表現次元、kはカーネル 畳み込みのサイズと制限付き自己注意における近傍のサイズ。 レイヤータイプ レイヤーごとの複雑さ 連続最大パス長 オペレーション 自己注意 O(n2·d) O(1) O(1) 再帰的 O(n·d²) O(n) O(n) 畳み込み O(k·n·d2) O(1) O(logk(n)) 自己注意(制限付き) O(r·n·d) O(1) O(n/r) 3.5 位置エンコーディング このモデルには再帰や畳み込みが含まれていないため、モデルがシーケンスの順序を利用するためには、シーケンスの相対的または絶対的な位置に関する情報を注入する必要があります。 シーケンス内のトークン。この目的のために、入力埋め込みに「位置エンコーディング」を追加します。 エンコーダスタックとデコーダスタックの底部。位置エンコーディングは埋め込みと同じ次元dmodelを持つため、両者を加算することができる。位置エンコーディングには多くの選択肢がある。 学習して固定した[9]。この研究では、異なる周波数の正弦関数と余弦関数を使用する。 PE(pos,2i)=sin(pos/100002i/dモデル) PE(pos,2i+1)=cos(pos/100002i/d model) ここで、pは位置、iは次元です。つまり、位置エンコーディングの各次元は正弦波に対応します。波長は2πから10000 ·2πまでの等比数列を形成します。 この関数を選択したのは、任意の固定オフセット k に対して PEpos+k は PEpos の線形関数として表すことができるため、モデルが相対位置で注意を向けることを容易に学習できると仮定したためです。 ... ... ... PyPDFの検出結果によると、PDF内の文字列を構造情報を保持せずに単一の長い文字列にシリアル化していることが判明しました。つまり、文書内の各行を改行文字 この制限は、ルールベースの PDF 解析方法に固有の特性です。 2.2 深層学習モデルに基づく分析手法この手法の利点は、文書全体のレイアウト(表やテキスト段落を含む)を正確に識別し、表の内部構造まで理解できることです。つまり、この手法では、文書の意図された意味と構造を維持しながら、文書を明確に定義された完全な情報単位に分割することができます。 ただし、この方法には一定の限界があります。物体検出とOCR処理には時間がかかる場合があります。そのため、特定の計算タスクを高速化するように設計されたGPUなどのハードウェアを使用し、複数のプロセスとスレッドを使用して並列処理を実行することをお勧めします。 この方法では、物体検出技術とOCRモデルを使用する必要があります。私は、代表的なオープンソースフレームワークをいくつかテストしました。
図4: 著者らが提案したPP-StructureV2フレームワーク。レイアウト情報抽出とキー情報抽出という2つのサブシステムを含む。出典: PP-StructureV2[9]。 上記のオープンソースツールに加えて、ChatDOCのような有料の商用ツールも存在します。これらの商用ツールは、文書レイアウトベースの認識とOCR(光学文字認識)方式を用いてPDF文書を解析します。 次に、オープンソースの非構造化[10]フレームワークを使用してPDFを解析し、次の3つの主要な課題に対処する方法について詳しく説明します。 チャレンジ1: 表や画像からデータを抽出する方法 このセクションでは、非構造化[10]フレームワークを例に挙げます。検出された表データはHTMLとして直接エクスポートできます。関連するコードは次のとおりです。 unstructured.partition.pdf から partition_pdf をインポート
filename = "/Users/Florian/Downloads/Attention_Is_All_You_Need.pdf"# infer_table_structure=True は自動的に hi_res を選択します strategyelements = partition_pdf(filename=filename, infer_table_structure=True)
tables = [el for el in elements if el.category == "Table"]
print(テーブル[0].テキスト)
print('--------------------------------------------------')
print(tables[0].metadata.text_as_html) partition_pdf 関数の内部コード ロジックをトレースすると、図 5 に示すような基本的なコード フローチャートが描画されます。 図5: partition_pdf関数の内部コードロジック。画像は著者による。 コードを実行した結果は次のようになります。 層の種類 自己注意 再帰畳み込み自己注意(制限付き) 層あたりの計算量 O(n2 · d) O(n · d2) O(k · n · d2) O(r · n · d) シーケンシャル最大パス長演算 O(1) O(n) O(1) O(1) O(1) O(n) O(logk(n)) O(n/r) -------------------------------------------------- <table><thead><th>レイヤータイプ</th><th>レイヤーあたりの複雑さ</th><th>シーケンシャルオペレーション</th><th>最大パス長</th></thead><tr><td>自己注意</td><td>O(n? - d)</td><td>O(1)</td><td>O(1)</td></tr><tr><td>再帰的</td><td>O(n- d?)</td><td>O(n)</td><td>O(n)</td></tr><tr><td>畳み込み</td><td>O(knd?)</td><td>O(1)</td><td>O(logy(n))</td></tr><tr><td>自己注意(制限付き)</td><td>O(rnd)</td><td>ol)</td><td>O(n/r)</td></tr></table> HTMLタグをコピーし、HTMLファイルとして保存します。そして、図6のようにChromeで開きます。 図 6: 図 3 の表 1 の内容の抽出。画像は著者によるものです。 ご覧のとおり、非構造化アルゴリズムはテーブル全体からほぼ正確にデータを抽出しました。 課題2: 検出されたデータブロックをどのように並べ替えるか?具体的には、2列のPDFをどのように処理するか? 2段組のPDFを扱う際には、論文「BERT: 言語理解のための深層双方向変換の事前学習」[11]を例に挙げます。赤い矢印は読む順番を示しています。 図7: 2段組ページ レイアウトが決定されると、図 8 に示すように、非構造化フレームによって各ページが複数の長方形ブロックに分割されます。 図8: レイアウト検出結果の視覚化。画像は著者による。 各長方形ブロックの詳細情報は、次の形式で取得できます。 [ LayoutElement(bbox=Rectangle(x1=851.1539916992188, y1=181.15073777777613, x2=1467.844970703125, y2=587.8204599999975), text='これらのアプローチは、文の埋め込み(Kiros et al., 2015; Logeswaran and Lee, 2018)や段落の埋め込み(Le and Mikolov, 2014)などのより粗い粒度に一般化されています。文の表現をトレーニングするために、以前の研究では、次の文の候補をランク付けする目的関数(Jernite et al., 2017; Logeswaran and Lee, 2018)、前の文の表現が与えられた場合の次の文の単語の左から右への生成(Kiros et al., 2015)、またはノイズ除去オートエンコーダーから導出された目的関数(Hill et al., 2016)。', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9519357085227966, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=196.5296173095703, y1=181.1507377777777, x2=815.468994140625, y2=512.548237777777), text='単語は文脈のみに基づいて分類されます。左から右への言語モデルの事前学習とは異なり、MLMの目的は、表現が左と右の文脈を融合することを可能にするため、事前に深い双方向Transformerを学習することができます。マスクされた言語モデルに加えて、テキストペア表現を共同で事前学習する「次の文予測」タスクも使用します。本論文の貢献は次のとおりです。', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9517233967781067、image_path=なし、parent=なし) LayoutElement(bbox=Rectangle(x1=200.22352600097656, y1=539.1451822222216, x2=825.0242919921875, y2=870.542682222221), text='• 言語表現における双方向事前学習の重要性を示します。事前学習に単方向言語モデルを使用するRadfordら(2018)とは異なり、BERTはマスクされた言語モデルを使用して事前学習済みの深い双方向表現を可能にします。これは、独立して学習された左から右への言語モデルと右から左への言語モデルを浅く連結するPetersら(2018a)とも対照的です。', source=<Source.YOLOX: 'yolox'>, type='List-item', prob=0.9414362907409668、image_path=なし、parent=なし) LayoutElement(bbox=Rectangle(x1=851.8727416992188, y1=599.8257377777753, x2=1468.0499267578125, y2=1420.4982377777742), text='ELMoとその前身(Peters et al., 2017, 2018a)は、従来の単語埋め込み研究を異なる次元で一般化しています。彼らは、左から右と右から左の言語モデルから文脈依存の特徴を抽出します。各トークンの文脈表現は、左から右と右から左の表現の連結です。文脈単語埋め込みを既存のタスク固有のアーキテクチャと統合することで、ELMoはいくつかの主要なNLPベンチマークの最先端技術を進歩させます(Peters et質問応答(Rajpurkar et al., 2016)、感情分析(Socher et al., 2013)、固有表現認識(Tjong Kim Sang and De Meulder, 2003)など、多くの研究が提案されている。Melamud et al. (2016)は、LSTMを用いて左右の文脈から単一の単語を予測するタスクを通して文脈表現を学習することを提案した。ELMoと同様に、彼らのモデルは特徴ベースであり、双方向性はそれほど高くない。Fedus et al. (2018)は、クローズタスクを用いてテキスト生成モデルの堅牢性を向上させることができることを示している。', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.938507616519928, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=199.3734130859375, y1=900.5257377777765, x2=824.69873046875, y2=1156.648237777776), text='• 事前学習済みの表現を用いることで、多くの高度に設計されたタスク固有のアーキテクチャの必要性が軽減されることを示しています。BERTは、文レベルおよびトークンレベルのタスクの大規模なスイートにおいて最先端のパフォーマンスを実現し、多くのタスク固有のアーキテクチャを上回る、微調整に基づく最初の表現モデルです。', source=<Source.YOLOX: 'yolox'>, type='List-item', prob=0.9461237788200378, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=195.5695343017578, y1=1185.526123046875, x2=815.9393920898438, y2=1330.3272705078125), text='• BERTは11のNLPタスクにおいて最先端の技術を進歩させます。コードと事前学習済みモデルはhttps://github.com/google-research/bertで入手できます。', source=<Source.YOLOX: 'yolox'>, type='List-item', prob=0.9213815927505493, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=195.33956909179688, y1=1360.7886962890625, x2=447.47264000000007, y2=1397.038330078125), text='2 Related Work ', source=<Source.YOLOX: 'yolox'>, type='Section-header', prob=0.8663332462310791, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=197.7477264404297, y1=1419.3353271484375, x2=817.3308715820312, y2=1527.54443359375), text='一般的な言語表現の事前学習には長い歴史があり、このセクションでは最も広く使用されているアプローチを簡単にレビューします。', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.928022563457489, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=851.0028686523438, y1=1468.341394166663, x2=1420.4693603515625, y2=1498.6444497222187), text='2.2 教師なし微調整アプローチ ', source=<Source.YOLOX: 'yolox'>, type='Section-header', prob=0.8346447348594666, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=853.544444444446, y1=1526.3701822222185, x2=1470.989990234375, y2=1669.5843488888852), text='特徴ベースのアプローチと同様に、この方向での最初の研究では、事前学習済みの単語特徴のみを使用しています(ラベルなしテキストからのパラメータの抽出)。(ロバートとウェストン、2008年)。', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9344717860221863, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=200.000000000000009, y1=1556.2037353515625, x2=799.1743774414062, y2=1588.031982421875), text='2.1 教師なし特徴ベースアプローチ ', source=<Source.YOLOX: 'yolox'>, type='Section-header', prob=0.8317819237709045, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=198.64227294921875, y1=1606.3146266666645, x2=815.2886352539062, y2=2125.895459999998), text='広く適用可能な単語表現の学習は、非ニューラル(Brown et al., 1992; Ando and Zhang, 2005; Blitzer et al., 2006)およびニューラル(Mikolov et al., 2013; Pennington et al., 2014)手法を含む、数十年にわたって研究が活発に行われている分野です。事前学習された単語埋め込みは、現代のNLPシステムの不可欠な部分であり、ゼロから学習された埋め込み(Turian単語埋め込みベクトルを事前学習するために、左から右への言語モデリングの目的(Mnih and Hinton, 2009)と、左と右の文脈における正しい単語と誤った単語を区別する目的(Mikolov et al., 2013)が使用されている。', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9450697302818298, image_path=None, parent=None), LayoutElement(bbox=Rectangle(x1=853.4905395507812, y1=1681.5868488888855, x2=1467.8729248046875, y2=2125.8954599999965), text='最近では、文脈的にトークン表現を生成する文や文書のエンコーダーがラベルなしテキストから事前学習され、教師あり下流タスク向けに微調整されています(Dai and Le, 2015; Howard and Ruder, 2018; Radford et al., 2018)。これらのアプローチの利点は、ゼロから学習する必要のあるパラメータがほとんどないことです。この利点の少なくとも一部により、OpenAI GPT(Radford et al., 2018)は、多くの文レベルのタスクで、これまで最先端の結果を達成しました。 GLUEベンチマーク(Wang言語モデル - Left-to-right et al., 2018a)。', source=<Source.YOLOX: 'yolox'>, type='Text', prob=0.9476840496063232, image_path=None, parent=None) ] ここで、(x1, y1) は左上の頂点の座標、(x2, y2) は右下の頂点の座標です。 (x_1, y_1) -------- | | | | | | ---------- (x_2, y_2) この時点で、ページの読み取り順序を変更できます。Unstructuredフレームワークにはソートアルゴリズムが組み込まれていますが、2列表示の場合、ソート結果が満足のいくものではないと感じました。 したがって、この状況に対処するためのアルゴリズムを設計する必要があります。最も簡単な方法は、まず左上の頂点のx座標でソートし、x座標が同じであればy座標でソートすることです。擬似コードは次のとおりです。 layout.sort(key=lambda z: (z.bbox.x1, z.bbox.y1, z.bbox.x2, z.bbox.y2)) しかし、同じ列内でもタイルのX座標は変化する可能性があることがわかりました。図9に示すように、紫色の線で示されたブロックのX座標はbbox.x1ですが、実際にはさらに左寄りです。ソートすると、このブロックは緑の線で示されたブロックよりも前に表示され、ドキュメントの読み上げ順序に明らかに違反しています。 図9: 同じ列でもX軸は変化する場合がある。画像は著者による。 この場合、実行可能なアルゴリズムは次のようになります。
x1_min = min([レイアウト内の el の el.bbox.x1]) x2_max = max([レイアウト内のelのel.bbox.x2]) 中間線のx座標 = (x2_max + x1_min) / 2 bbox.x1 < mid_line_x_coordinate の場合、ブロックは左列の一部とみなされます。それ以外の場合は、右列の一部とみなされます。 分類後、各列内の各ブロックをY座標に従って並べ替えます。最後に、右側の列を左側の列の右側に接続します。 左列 = [] 右列 = [] レイアウト内のelの場合: el.bbox.x1 < mid_line_x_coordinate の場合: left_column.append(el) それ以外の場合: 右列に追加(el) left_column.sort(キー = lambda z: z.bbox.y1) right_column.sort(キー = lambda z: z.bbox.y1) sorted_layout = 左列 + 右列 このアルゴリズムの改善は、単一列の PDF の解析にも対応していることは注目に値します。 課題3: 複数レベルの見出しを抽出する方法 見出し(複数レベルの見出しを含む)を抽出する目的は、LLM によって提供される応答の精度を高めることです。 たとえば、ユーザーが図 9 のセクション 2.1 の要点を理解したい場合、セクション 2.1 のタイトルを正確に抽出し、関連するコンテンツとともにコンテキストとして LLM に送信するだけで済みます。これにより、最終的な応答の精度が大幅に向上します。 このアルゴリズムは、図9に示すレイアウトブロックに依存しています。type='Section-header'のブロックを抽出し、高さの差(bbox.y2 - bbox.y1)を計算します。高さの差が最も大きいブロックが第1レベルの見出しに対応し、次に第2レベルの見出し、そして第3レベルの見出しが続きます。 2.3 マルチモーダル大規模モデルに基づくPDFの複雑な構造の解析マルチモーダルモデルの急速な発展と広範な応用により、表の解析にも利用できるようになりました。いくつかの選択肢があります[12]。
テストの結果、3 番目の方法が最も効果的であると判断されました。 さらに、図 10 に示すように、マルチモーダル モデルを使用して、画像から重要な情報を抽出または要約することもできます (PDF ファイルは簡単に画像に変換できるため)。 図10:画像から重要な情報を抽出または要約する。出典:GPT-4 with Vision:完全ガイドと評価[13] 03 結論ほぼすべての非構造化文書は非常に柔軟性が高く、様々な解析手法が必要となります。しかし、どの手法を用いるべきかについては、現在業界内でコンセンサスが得られていません。 この場合、プロジェクトのニーズに最適な方法を選択し、PDFファイルの種類に応じて適切な処理方法を採用することをお勧めします。例えば、論文、書籍、財務諸表などの非構造化文書では、その特性に応じて独自のレイアウト設計が必要になる場合があります。 それでも、条件が許せば、ディープラーニングベースまたはマルチモーダルな手法を選択することをお勧めします。これらの手法は、文書を明確に定義された完全な情報単位に効果的に分割し、文書本来の意味と構造を可能な限り維持することができます。 読んでくれてありがとう! ———— フロリアン・ジューン 人工知能の研究者。主に大規模言語モデル、データ構造とアルゴリズム、NLP に関する記事を書いています。 終わり
|