opendatalab / MinerU

A one-stop, open-source, high-quality data extraction tool, supports PDF/webpage/e-book extraction.一站式开源高质量数据提取工具,支持PDF/网页/多格式电子书提取。
https://mineru.readthedocs.io/
GNU Affero General Public License v3.0
14.83k stars 1.1k forks source link

使用的detect_language工具包极其不稳定,不建议继续使用 #328

Closed ConleyKong closed 3 months ago

ConleyKong commented 3 months ago

Description of the bug | 错误描述

detect_lang('2.总结2023的经验做法,修订')这个中文文本竟然检测成了tr语种?太不靠谱了吧?

How to reproduce the bug | 如何复现

libs/language.py下直接调用: print(detect_lang('2.总结2023的经验做法,修订')) 可以复现该现象,去除2.后变成中文,就很不靠谱

Operating system | 操作系统

Windows

Python version | Python 版本

3.10

Software version | 软件版本 (magic-pdf --version)

0.6.x

Device mode | 设备模式

cuda

myhloli commented 3 months ago

早期版本是使用的pycld2作为语言检测工具,后期为了全平台兼容,将pycld2更换为fast_langdetect,虽然语言检测精度略有降低,但是获得了更好的兼容性。

您提供的这个案例已经得到复现,而且在pycld2上明显可以观察到在这个案例上表现比fast_langdetect更好。

考虑到语言识别目前主要有两个功能:

  1. 判断是否是需要分词的长英文单词
  2. 判断span拼接是否需要添加空格

目前这两个需求使用fast_langdetect没发现有什么太大的bug,如果您对语言检测的准确率要求比较高,可以使用pycld2替换fast_langdetect

附上pycld2实现代码

import pycld2 as cld2
import regex
import unicodedata

RE_BAD_CHARS = regex.compile(r"\p{Cc}|\p{Cs}")

def remove_bad_chars(text):
    return RE_BAD_CHARS.sub("", text)
def detect_lang(text: str) -> str:
    if len(text) == 0:
        return ""

    try:
        _, _, details = cld2.detect(text)
    except:
        # cld2 doesn't like control characters
        # https://github.com/mikemccand/chromium-compact-language-detector/issues/22#issuecomment-435904616
        html_no_ctrl_chars = ''.join([l for l in text if unicodedata.category(l)[0] not in ['C',]])
        _, _, details = cld2.detect(html_no_ctrl_chars)
    lang = ""
    try:
        lang = details[0][1].lower()
    except:
        lang = ""
    return lang

if __name__ == '__main__':
    print(detect_lang("This is a test."))
    print(detect_lang("<html>This is a test</html>"))
    print(detect_lang("这个是中文测试。"))
    print(detect_lang("<html>这个是中文测试。</html>")) 
    print(detect_lang("<html>这个是中文测试。</html>"))
ConleyKong commented 3 months ago

早期版本是使用的pycld2作为语言检测工具,后期为了全平台兼容,将pycld2更换为fast_langdetect,虽然语言检测精度略有降低,但是获得了更好的兼容性。

您提供的这个案例已经得到复现,而且在pycld2上明显可以观察到在这个案例上表现比fast_langdetect更好。

考虑到语言识别目前主要有两个功能:

  1. 判断是否是需要分词的长英文单词
  2. 判断span拼接是否需要添加空格

目前这两个需求使用fast_langdetect没发现有什么太大的bug,如果您对语言检测的准确率要求比较高,可以使用pycld2替换fast_langdetect

附上pycld2实现代码

import pycld2 as cld2
import regex
import unicodedata

RE_BAD_CHARS = regex.compile(r"\p{Cc}|\p{Cs}")

def remove_bad_chars(text):
    return RE_BAD_CHARS.sub("", text)
def detect_lang(text: str) -> str:
    if len(text) == 0:
        return ""

    try:
        _, _, details = cld2.detect(text)
    except:
        # cld2 doesn't like control characters
        # https://github.com/mikemccand/chromium-compact-language-detector/issues/22#issuecomment-435904616
        html_no_ctrl_chars = ''.join([l for l in text if unicodedata.category(l)[0] not in ['C',]])
        _, _, details = cld2.detect(html_no_ctrl_chars)
    lang = ""
    try:
        lang = details[0][1].lower()
    except:
        lang = ""
    return lang

if __name__ == '__main__':
    print(detect_lang("This is a test."))
    print(detect_lang("<html>This is a test</html>"))
    print(detect_lang("这个是中文测试。"))
    print(detect_lang("<html>这个是中文测试。</html>")) 
    print(detect_lang("<html>这个是中文测试。</html>"))

好的,我一般处理的都是中文,所以我直接让他不检测全部使用中文了,哈哈哈,直接改源码了