Python 如何从下面的段落中得到第一句话?

Python 如何从下面的段落中得到第一句话?,python,nlp,text-segmentation,Python,Nlp,Text Segmentation,我知道这听起来很容易。我曾想过使用第一个点(.)作为基准,但当缩写和缩写出现时,我就无能为力了 e、 g.- 温斯顿·伦纳德·斯宾塞·丘吉尔爵士,KG,OM,CH,TD,PC,DL,FRS, 亲爱的。RA(1874年11月30日至1965年1月24日)是英国政治家 他是一位政治家,以在二战期间对英国的领导而闻名 第二次世界大战。他被广泛认为是最伟大的作家之一 战时领导人,曾两次担任首相。著名的政治家 作为演说家,丘吉尔也是英国军队的一名军官,一位 历史学家、作家和艺术家 这里,第一个点是Hon.

我知道这听起来很容易。我曾想过使用第一个点(.)作为基准,但当缩写和缩写出现时,我就无能为力了

e、 g.-

温斯顿·伦纳德·斯宾塞·丘吉尔爵士,KG,OM,CH,TD,PC,DL,FRS, 亲爱的。RA(1874年11月30日至1965年1月24日)是英国政治家 他是一位政治家,以在二战期间对英国的领导而闻名 第二次世界大战。他被广泛认为是最伟大的作家之一 战时领导人,曾两次担任首相。著名的政治家 作为演说家,丘吉尔也是英国军队的一名军官,一位 历史学家、作家和艺术家

这里,第一个点是Hon.,但我想要完整的第一行,以第二次世界大战结束


可能是人吗?

这通常是不可能的。缩写词、数值(“23.45美元”、“32.5度”)、引语(“他说:‘哈!你永远不会……’”)或带有标点符号的名字(例如:“在迪斯科舞厅惊慌!”),甚至括号中的整个从句基本上都是他们自己的句子(“厨师(他也是一位出色的画家!)[……”)这意味着你不能仅仅用点和感叹号/问号分割文本,也不能使用任何其他“简单”的方法


基本上,为了解决一般情况,您需要一个自然语言解析器(在这种情况下,您最好使用prolog而不是python),该解析器的语法可以处理所有这些特殊情况。如果你能将问题简化为一个不太一般的问题,例如只需要处理缩写和引语,你也许能解决一些问题,但你仍然需要任何类型的解析器或状态机,因为正则表达式对于这类事情来说还不够强大。

你有没有研究过自然语言工具包,nltk?它似乎有一个可用的句子标记器

如果使用
nltk
可以添加缩写,如下所示:

>>> import nltk
>>> sent_detector = nltk.data.load('tokenizers/punkt/english.pickle')
>>> sent_detector._params.abbrev_types.add('hon')
>>> sent_detector.tokenize(your_text)
['Sir Winston Leonard Spencer-Churchill, KG, OM, CH, TD, PC, DL, FRS, Hon. RA 
(30 November 1874 \xe2\x80\x93 24 January 1965) was a British politician and 
statesman known for his leadership of the United Kingdom during the Second 
World War.', 
'He is widely regarded as one of the great wartime leaders and served as Prime 
Minister twice.', 
'A noted statesman and orator, Churchill was also an officer in the British Army,
a historian, a writer, and an artist.']
该方法基于,该方法报告,根据测试语料库,Punkt的F分数(精确性和召回率的调和平均值)在91%到99%之间

吻,蒂博,还有简·斯特伦克。2006“无监督的多语言句子
边界探测”。计算语言学,(32)485-525。

维基百科上的第一句话几乎总是说什么是,过去是,现在是或曾经是。因此,一个可能的解决办法是在找到一个连接动词(is,was,are,were)之前不要结束句子。当然,这不会100%准确地工作,但这里有一个可能的解决方案:

def get_first_sentence(my_string):

    linking_verbs = set(['was', 'is', 'are', 'were'])

    split_string = my_string.split(' ')

    first_sentence = []
    linked_verb_booly = False
    for ele in split_string:
        first_sentence.append(ele)
        if ele in linking_verbs:
            linked_verb_booly = True
        if '.' in ele and linked_verb_booly == True:
            break

    return ' '.join(first_sentence)
例1:

温斯顿·伦纳德·斯宾塞·丘吉尔爵士,KG,OM,CH,TD,PC,DL,FRS, 亲爱的。RA(1874年11月30日至1965年1月24日)是英国政治家 他是一位政治家,以在二战期间对英国的领导而闻名 第二次世界大战。他被广泛认为是最伟大的作家之一 战时领导人,曾两次担任首相。著名的政治家 作为演说家,丘吉尔也是英国军队的一名军官,一位 历史学家、作家和艺术家

结果:

>>> first_sentence_1
'Sir Winston Leonard Spencer-Churchill, KG, OM, CH, TD, PC, DL, FRS, Hon. RA (30 November 1874 \xe2\x80\x93 24 January 1965) was a British politician and statesman known for his leadership of the United Kingdom during the Second World War.'
>>> first_sentence_2
'Python is a general-purpose, high-level programming language[11] whose design philosophy emphasizes code readability.'
>>> first_sentence_3

    "China (Listeni/\xcb\x88t\xca\x83a\xc9\xaan\xc9\x99/; Chinese: \xe4\xb8\xad\xe5\x9b\xbd; pinyin: Zh\xc5\x8dnggu\xc3\xb3; see also Names of China), officially the People's Republic of China (PRC), is the world's most-populous country, with a population of over 1.3"
例2:

Python是一种通用的高级编程语言[11] 设计理念强调代码可读性。它的语法据说是 要清晰[12]且富有表现力。[13]Python有一个庞大而全面的 标准图书馆[14]

结果:

>>> first_sentence_1
'Sir Winston Leonard Spencer-Churchill, KG, OM, CH, TD, PC, DL, FRS, Hon. RA (30 November 1874 \xe2\x80\x93 24 January 1965) was a British politician and statesman known for his leadership of the United Kingdom during the Second World War.'
>>> first_sentence_2
'Python is a general-purpose, high-level programming language[11] whose design philosophy emphasizes code readability.'
>>> first_sentence_3

    "China (Listeni/\xcb\x88t\xca\x83a\xc9\xaan\xc9\x99/; Chinese: \xe4\xb8\xad\xe5\x9b\xbd; pinyin: Zh\xc5\x8dnggu\xc3\xb3; see also Names of China), officially the People's Republic of China (PRC), is the world's most-populous country, with a population of over 1.3"
例3:

中国(李斯特)中国; 拼音:Zhōngguó;另见姓名 正式名称为中华人民共和国(PRC),是 世界上人口最多的国家,人口超过13亿。 东亚区域占地约960万平方公里 该州是世界上陆地面积第二大的国家,[13]和 总面积第三或第四大,取决于 总面积[14]

结果:

>>> first_sentence_1
'Sir Winston Leonard Spencer-Churchill, KG, OM, CH, TD, PC, DL, FRS, Hon. RA (30 November 1874 \xe2\x80\x93 24 January 1965) was a British politician and statesman known for his leadership of the United Kingdom during the Second World War.'
>>> first_sentence_2
'Python is a general-purpose, high-level programming language[11] whose design philosophy emphasizes code readability.'
>>> first_sentence_3

    "China (Listeni/\xcb\x88t\xca\x83a\xc9\xaan\xc9\x99/; Chinese: \xe4\xb8\xad\xe5\x9b\xbd; pinyin: Zh\xc5\x8dnggu\xc3\xb3; see also Names of China), officially the People's Republic of China (PRC), is the world's most-populous country, with a population of over 1.3"
您可以在上一个示例中看到限制,该示例中的句子被截断为“早”,因为“.”在1.3中

此外,使用正则表达式进行上述操作可能更好


这只是一个想法。

虽然这里的许多人都有自己的优点,但自然语言处理实际上是一项非常困难的任务,人们对它进行了大量的研究,但结果却非常不可靠。然而,目前还没有解决方案。很多人都提到了自然语言工具包,它是现存最强大的自然语言处理工具之一。NLTK实际上有一个现成的句子标记器,虽然它并不完美,但非常好。它被称为PunktSentenceTokenizer,可以很好地过滤缩写。更多的俚语会给它带来很多麻烦,但是对于像你上面提到的一句小说来说,它的效果非常好。文档可在此处找到:


遗憾的是,它实际上并不适用于您提出的示例,但它确实有一个非常详细的查找,并捕获了许多缩写。我认为这个例子中的很多项目是“Hon.”也是一个专有名词,字典可能会这么看。可以在nltk中自定义配置您的词典,以捕获这种特殊情况,如fraxel的回答中所述。但是,简单的标记器不会捕获许多其他缩写、价格符号或其他此类常见情况,如果你坚持句点结束句子的惯例,只有在句点后面跟一个空格或新行时,你才能这样做:

s="Sir Winston Leonard Spencer-Churchill, KG, OM, CH, TD, PC, DL, FRS, Hon. RA (30 November 1874 – 24 January 1965) was a British politician and statesman known for his leadership of the United Kingdom during the Second World War. He is widely regarded as one of the great wartime leaders and served as Prime Minister twice. A noted statesman and orator, Churchill was also an officer in the British Army, a historian, a writer, and an artist."
sentence_delimiters = ['. ', '.\n', '? ', '?\n', '! ', '!\n']
pos = [s.find(delimiter) for delimiter in sentence_delimiters]
pos = min([p for p in pos if p >= 0])
print s[:pos]

什么规则说,
Hon.
中的点不结束句子?它不。。。亲爱的。RA只是一个标题。Bruno:-)那么,选择语言的完整语法分析器呢?这不是有点过分,甚至不可能吗?语言并不总是严格遵守语法。我认为一些限制是为了使这成为一个可解决的问题。我知道这可能很难,因为涉及到语言问题。。。。但这听起来很简单。。。你必须先到