Python實現(xiàn)準確獲取PDF文件中的標題
想要在PDF文件中,解析獲取全部的標題,是一件比較麻煩的事情。正是因為PDF文件中的內(nèi)容可能是五花八門的格式(論文、財報、法律條文、圖書、報紙、等等)。
但是獲取標題信息,又是一件非常重要的事情。標題中往往蘊含著非常多的概括性信息。本文將介紹一種較為準確的提取標題的方式。使用python組件+LLM。本文會給出調(diào)試后的可運行代碼,以及prompt,還有運行結果。
本文測試以一篇微軟的論文為例。論文地址:https://arxiv.org/pdf/2303.07678.pdf
一、技術選型
python組件使用 PyMuPDF,模型使用通義千問。
二、安裝使用 pdf解析工具 PyMuPDF
2.1 PyMuPDF安裝方式
pip install PyMuPDF
2.2 調(diào)試后的代碼
import fitz def extract_titles_from_pdf(pdf_path, thres=1.1): doc = fitz.open(pdf_path) titles = [] for page_num in range(len(doc)): page = doc.load_page(page_num) blocks = page.get_text("dict")["blocks"] # 獲取當前頁的頁碼 page_number = page_num + 1 # 尋找每一頁可能的標題 page_titles = [] for block in blocks: # 獲取文本塊的字體大小 sizes = [span["size"] for line in block["lines"] for span in line["spans"]] avg_size = sum(sizes) / max(len(sizes), 1) # 判斷是否可能是標題 if avg_size > thres: text = " ".join([span["text"] for line in block["lines"] for span in line["spans"]]) # 排除正文、表格、圖片和公式,只保留可能的標題 if not is_body_text(text) and not is_table(text) and not is_image(text) and not is_formula(text): # 將標題、頁碼添加到結果中 page_titles.append((text.strip(), page_number)) # 將該頁的標題添加到結果列表中 titles += page_titles return titles def is_body_text(text): # 根據(jù)文本的長度和內(nèi)容等特征,判斷是否為正文 # 這里可以根據(jù)具體的PDF文件的特點來定義規(guī)則 # 以下只是一個示例,可能需要根據(jù)實際情況進行調(diào)整 return len(text) > 100 or text.endswith(".") or text.endswith("?") or text.endswith("!") def is_table(text): # 根據(jù)文本的結構和內(nèi)容特征,判斷是否為表格 # 這里可以根據(jù)表格的特點來定義規(guī)則 # 以下只是一個示例,可能需要根據(jù)實際情況進行調(diào)整 return " " in text or "\t" in text or " | " in text def is_image(text): # 根據(jù)文本的特征,判斷是否為圖像 # 這里可以根據(jù)圖像的特點來定義規(guī)則 # 以下只是一個示例,可能需要根據(jù)實際情況進行調(diào)整 return text.startswith("Image:") or text.startswith("Figure:") def is_formula(text): # 根據(jù)文本的特征,判斷是否為公式 # 這里可以根據(jù)公式的特點來定義規(guī)則 # 以下只是一個示例,可能需要根據(jù)實際情況進行調(diào)整 return text.startswith("Formula:") or text.startswith("Equation:") # 指定要解析的 PDF 文件路徑 pdf_path = "D:\\angus\\工作文檔\\paper\\Rewrite\\微軟query擴寫 Query2doc Query Expansion with Large Language Models-2303.07678.pdf" # 調(diào)用函數(shù)提取標題內(nèi)容 titles_with_page_numbers = extract_titles_from_pdf(pdf_path) # 打印提取到的標題內(nèi)容和對應的頁碼 for i, (title, page_number) in enumerate(titles_with_page_numbers): print(f"Title {i + 1}: {title} (Page {page_number})")
2.3 輸出的效果
此時,輸出比較亂,還不能找到標題,但是標題已經(jīng)藏在了下邊的內(nèi)容中。接下來就是如何挖掘到真正的標題。
Title 1: Query2doc: Query Expansion with Large Language Models (Page 1)
Title 2: Abstract (Page 1)
Title 3: 1 Introduction (Page 1)
Title 4: 2 Method (Page 2)
Title 5: Write a passage that answers the given query: (Page 2)
Title 6: LLM Prompts (Page 2)
Title 7: LLM Output (Page 2)
Title 8: Method Fine-tuning MS MARCO dev TREC DL 19 TREC DL 20 (Page 3)
Title 9: MRR@10 R@50 R@1k nDCG@10 nDCG@10 (Page 3)
Title 10: Sparse retrieval BM25 ? 18.4 58.5 85.7 51.2 ∗ 47.7 ∗ (Page 3)
Title 11: + query2doc ? 21.4 +3.0 65.3 +6.8 91.8 +6.1 66.2 +15.0 62.9 +15.2 (Page 3)
Title 12: BM25 + RM3 ? 15.8 56.7 86.4 52.2 47.4 docT5query ( Nogueira and Lin ) ? 27.7 75.6 94.7 64.2 - (Page 3)
Title 13: 3 Experiments (Page 3)
Title 14: 3.1 Setup (Page 3)
Title 15: 3.2 Main Results (Page 3)
Title 16: 4 Analysis (Page 3)
Title 17: DBpedia NFCorpus Scifact Trec-Covid Touche2020 (Page 4)
Title 18: BM25 31.3 32.5 66.5 65.6 36.7 + query2doc 37.0 +5.7 34.9 +2.4 68.6 +2.1 72.2 +6.6 39.8 +3.1 (Page 4)
Title 19: # params TREC 19 TREC 20 (Page 4)
Title 20: 1 10 30 50 100 (Page 4)
Title 21: % labeled data for fine-tuning (Page 4)
Title 22: 20 (Page 4)
Title 23: 22 (Page 4)
Title 24: 24 (Page 4)
Title 25: 26 (Page 4)
Title 26: 28 (Page 4)
Title 27: 30 (Page 4)
Title 28: 32 (Page 4)
Title 29: 34 (Page 4)
Title 30: 36 (Page 4)
Title 31: MRR on dev set (Page 4)
Title 32: 21.4 (Page 4)
Title 33: 27.3 (Page 4)
Title 34: 31.4 (Page 4)
Title 35: 32.8 (Page 4)
Title 36: 33.7 (Page 4)
Title 37: 22.7 (Page 4)
Title 38: 28.5 (Page 4)
Title 39: 32.1 (Page 4)
Title 40: 34.1 (Page 4)
Title 41: 35.1 (Page 4)
Title 42: DPR w/o query2doc DPR w/ query2doc (Page 4)
Title 43: TREC 19 TREC 20 (Page 4)
Title 44: BM25 + query2doc 66.2 62.9 w/ query only 51.2 47.7 w/ pseudo-doc only 48.7 44.5 (Page 4)
Title 45: 1 Refer to https://en.wikipedia.org/wiki/It’s_a_ Jungle_Out_There_(song) (Page 4)
Title 46: query who killed nicholas ii of russia (Page 5)
Title 47: query who sings monk theme song (Page 5)
Title 48: 5 Related Work (Page 5)
Title 49: 6 Conclusion (Page 5)
Title 50: Limitations (Page 6)
Title 51: LLM call Index search (Page 6)
Title 52: BM25 - 16ms + query2doc >2000ms 177ms (Page 6)
Title 53: References (Page 6)
Title 54: Vladimir Karpukhin, Barlas Oguz, Sewon Min, Patrick Lewis, Ledell Wu, Sergey Edunov, Danqi Chen, and (Page 6)
Title 55: A Implementation Details (Page 8)
Title 56: DPR w/ distillation (Page 8)
Title 57: For dense retrieval experiments in Table (Page 8)
Title 58: B Exploring Other Prompting Strategies (Page 8)
Title 59: DL 2019 DL 2020 (Page 8)
Title 60: Query2doc 69.2 64.5 + iterative prompt 68.6 64.8 (Page 8)
Title 61: Query: {{query}} (Page 8)
Title 62: # Begin of passage {{passage}} # End of passage (Page 8)
Title 63: query who sings hey good looking (Page 9)
Title 64: query trumbull marriott fax number (Page 9)
Title 65: query what is hra and hsa (Page 9)
Title 66: DL 2019 DL 2020 (Page 9)
Title 67: Average 64.8 60.9 Std dev. ± 1.14 ± 1.63 (Page 9)
Title 68: C Results Across Multiple Runs (Page 9)
Title 69: prompts (Page 10)
Title 70: Write a passage that answers the given query: (Page 10)
三、使用LLM提取標題
期初,我還想通過規(guī)則來挖掘到真正的標題。實際上由于文件五花八門,我們很難通過一個標準的規(guī)則去適應各種各樣的文件?;艘簧衔绲臅r間,連一篇論文的標題都沒能準確的提取出來。更何況去適配千奇百怪的文件呢?最后效果不一定好,而且會把自己累死。
于是想到了LLM,嘗試用LLM來提煉上個步驟中的輸出。
這里使用的是阿里的通義千問。
3.1 prompt
以下是一個文件的內(nèi)容,請幫我分析提取真正的標題。
要求:只需要根據(jù)內(nèi)容,判斷是否可以是標題。不要額外生成任何內(nèi)容!!
內(nèi)容如下 :
{Title 1: Query2doc: Query Expansion with Large Language Models (Page 1)
Title 2: Abstract (Page 1)
Title 3: 1 Introduction (Page 1)
Title 4: 2 Method (Page 2)
Title 5: Write a passage that answers the given query: (Page 2)
Title 6: LLM Prompts (Page 2)
Title 7: LLM Output (Page 2)
Title 8: Method Fine-tuning MS MARCO dev TREC DL 19 TREC DL 20 (Page 3)
Title 9: MRR@10 R@50 R@1k nDCG@10 nDCG@10 (Page 3)
Title 10: Sparse retrieval BM25 ? 18.4 58.5 85.7 51.2 ∗ 47.7 ∗ (Page 3)
Title 11: + query2doc ? 21.4 +3.0 65.3 +6.8 91.8 +6.1 66.2 +15.0 62.9 +15.2 (Page 3)
Title 12: BM25 + RM3 ? 15.8 56.7 86.4 52.2 47.4 docT5query ( Nogueira and Lin ) ? 27.7 75.6 94.7 64.2 - (Page 3)
Title 13: 3 Experiments (Page 3)
Title 14: 3.1 Setup (Page 3)
Title 15: 3.2 Main Results (Page 3)
Title 16: 4 Analysis (Page 3)
Title 17: DBpedia NFCorpus Scifact Trec-Covid Touche2020 (Page 4)
Title 18: BM25 31.3 32.5 66.5 65.6 36.7 + query2doc 37.0 +5.7 34.9 +2.4 68.6 +2.1 72.2 +6.6 39.8 +3.1 (Page 4)
Title 19: # params TREC 19 TREC 20 (Page 4)
Title 20: 1 10 30 50 100 (Page 4)
Title 21: % labeled data for fine-tuning (Page 4)
Title 22: 20 (Page 4)
Title 23: 22 (Page 4)
Title 24: 24 (Page 4)
Title 25: 26 (Page 4)
Title 26: 28 (Page 4)
Title 27: 30 (Page 4)
Title 28: 32 (Page 4)
Title 29: 34 (Page 4)
Title 30: 36 (Page 4)
Title 31: MRR on dev set (Page 4)
Title 32: 21.4 (Page 4)
Title 33: 27.3 (Page 4)
Title 34: 31.4 (Page 4)
Title 35: 32.8 (Page 4)
Title 36: 33.7 (Page 4)
Title 37: 22.7 (Page 4)
Title 38: 28.5 (Page 4)
Title 39: 32.1 (Page 4)
Title 40: 34.1 (Page 4)
Title 41: 35.1 (Page 4)
Title 42: DPR w/o query2doc DPR w/ query2doc (Page 4)
Title 43: TREC 19 TREC 20 (Page 4)
Title 44: BM25 + query2doc 66.2 62.9 w/ query only 51.2 47.7 w/ pseudo-doc only 48.7 44.5 (Page 4)
Title 45: 1 Refer to https://en.wikipedia.org/wiki/It’s_a_ Jungle_Out_There_(song) (Page 4)
Title 46: query who killed nicholas ii of russia (Page 5)
Title 47: query who sings monk theme song (Page 5)
Title 48: 5 Related Work (Page 5)
Title 49: 6 Conclusion (Page 5)
Title 50: Limitations (Page 6)
Title 51: LLM call Index search (Page 6)
Title 52: BM25 - 16ms + query2doc >2000ms 177ms (Page 6)
Title 53: References (Page 6)
Title 54: Vladimir Karpukhin, Barlas Oguz, Sewon Min, Patrick Lewis, Ledell Wu, Sergey Edunov, Danqi Chen, and (Page 6)
Title 55: A Implementation Details (Page 8)
Title 56: DPR w/ distillation (Page 8)
Title 57: For dense retrieval experiments in Table (Page 8)
Title 58: B Exploring Other Prompting Strategies (Page 8)
Title 59: DL 2019 DL 2020 (Page 8)
Title 60: Query2doc 69.2 64.5 + iterative prompt 68.6 64.8 (Page 8)
Title 61: Query: {{query}} (Page 8)
Title 62: # Begin of passage {{passage}} # End of passage (Page 8)
Title 63: query who sings hey good looking (Page 9)
Title 64: query trumbull marriott fax number (Page 9)
Title 65: query what is hra and hsa (Page 9)
Title 66: DL 2019 DL 2020 (Page 9)
Title 67: Average 64.8 60.9 Std dev. ± 1.14 ± 1.63 (Page 9)
Title 68: C Results Across Multiple Runs (Page 9)
Title 69: prompts (Page 10)
Title 70: Write a passage that answers the given query: (Page 10)}
3.2 LLM最后的輸出
基于內(nèi)容分析,真正的標題可能包括但不限于以下幾項:
Title 1: Query2doc: Query Expansion with Large Language Models (Page 1)
Title 2: Abstract (Page 1)
Title 3: 1 Introduction (Page 1)
Title 4: 2 Method (Page 2)
Title 13: 3 Experiments (Page 3)
Title 16: 4 Analysis (Page 3)
Title 48: 5 Related Work (Page 5)
Title 49: 6 Conclusion (Page 5)
Title 50: Limitations (Page 6)
Title 53: References (Page 6)
Title 55: A Implementation Details (Page 8)
Title 56: DPR w/ distillation (Page 8)
Title 58: B Exploring Other Prompting Strategies (Page 8)
Title 68: C Results Across Multiple Runs (Page 9)
以上這些標題通常在學術論文或其他類型的技術文檔中作為各個主要部分的標題使用,它們標識了文檔結構的不同章節(jié)和內(nèi)容主題。其他帶有編號的行更多的是文檔內(nèi)的副標題、子章節(jié)、表格標題或具體的數(shù)據(jù)說明,而非一級或二級標題。
四、結論
在經(jīng)過LLM以后,最終標題提取的準確率已經(jīng)非常高了!除了提取出來標題,我們還獲取到了頁碼。此時還可以去PDF頁面導航了。
不管是什么樣格式的文件,我們都可以先解析,大致獲取標題,可能不準確。然后再過一次模型,即可獲取到準確的標題。
五、思考
當涉及到版面分析時,可以使用文本塊的布局信息來判斷標題。具體來說,可以根據(jù)文本塊的相對位置和字體大小等信息來識別可能的標題。以下是一種可能的思路:
檢測文本塊的位置:首先,遍歷每一頁的文本塊,并獲取它們的位置信息??梢钥紤]使用文本塊的坐標信息,例如左上角和右下角的坐標。
檢測文本塊的字體大?。簩τ诿總€文本塊,可以獲取其包含文本的字體大小。這將有助于識別較大的文本塊,通常標題的字體大小較大。
根據(jù)位置和字體大小判斷標題:結合文本塊的位置和字體大小信息,可以應用一些啟發(fā)式規(guī)則來判斷哪些文本塊可能是標題。例如,可以考慮位于頁面頂部且字體較大的文本塊,或者是與上一文本塊的垂直距離較遠的文本塊。
合并相鄰文本塊:有時候,標題可能被分割成多個文本塊。在識別可能的標題后,可以嘗試將相鄰的文本塊合并成一個標題。
去除重復和錯誤的標題:在提取了所有可能的標題后,可以進行一些后處理步驟,例如去除重復的標題或者根據(jù)一些特定規(guī)則去除錯誤的標題。
綜上所述,通過結合文本塊的位置和字體大小信息,可以設計一種版面分析的方法來提取 PDF 文件中的標題。這種方法可能會更加準確和可靠,因為它更多地利用了文本的布局信息。
以上就是Python實現(xiàn)準確獲取PDF文件中的標題的詳細內(nèi)容,更多關于Python獲取PDF文件標題的資料請關注腳本之家其它相關文章!
相關文章
Python使用email模塊對郵件進行編碼和解碼的實例教程
Python中我們一般使用SMTP模塊來首發(fā)郵件,而用email模塊來處理郵件編碼,本文我們就來詳細看一下Python使用email模塊對郵件進行編碼和解碼的實例教程,需要的朋友可以參考下2016-07-07Python OpenCV實現(xiàn)按照像素點圖片切割
本文將詳細介紹如何使用Python和OpenCV進行基于像素點的圖像分割,包括閾值分割,自適應閾值分割等,感興趣的小伙伴可以跟隨小編一起學習一下2024-12-12pandas.DataFrame中提取特定類型dtype的列
本文主要介紹了pandas.DataFrame中提取特定類型dtype的列,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-02-02python實現(xiàn)代碼行數(shù)統(tǒng)計示例分享
這篇文章主要介紹了python實現(xiàn)代碼行數(shù)統(tǒng)計的示例,需要的朋友可以參考下2014-02-02使用Keras中的ImageDataGenerator進行批次讀圖方式
這篇文章主要介紹了使用Keras中的ImageDataGenerator進行批次讀圖方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06