4

我知道这听起来很容易。我想过用第一个点(。)作为基准,但是当缩写和短形式出现时,我感到无助。

例如 -

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

在这里,第一个点是 Hon.,但我想要在 Second World War 结束的完整第一行。

人有可能吗???

4

6 回答 6

8

如果您使用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.']

这种方法基于Kiss & Strunk 2006,该报告报告说,Punkt 的 F 分数(准确率和召回率的调和平均值)在 91% 到 99% 之间,具体取决于测试语料库。

基斯、蒂博尔和扬·斯特伦克。2006.“无监督多语言句子边界检测”。 计算语言学,(32)485-525。

于 2012-06-18T14:05:07.507 回答
1

这一般是不可能的。缩写、数值(“$23.45”、“32.5 度”)、引文(“他说:'哈!你永远不会 [...]'”)或带有标点符号的名称(例如“Panic!At the Disco”)甚至括号中的整个从句基本上是他们自己的句子(“厨师(他也是一位出色的画家!)[...]”)意味着你不能只用点和感叹号/问号来分割文本或使用任何其他“简单”方法。

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

于 2012-06-18T12:59:31.133 回答
1

您是否研究过自然语言工具包 nltk?它似乎有一个句子标记器可用。http://nltk.googlecode.com/svn/trunk/doc/api/nltk.tokenize-module.html

于 2012-06-18T13:14:03.217 回答
0

维基百科上的第一句话几乎总是说什么is, was, are or were。因此,一个可能的解决方案是在达到连接动词(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,Hon。RA(1874 年 11 月 30 日 - 1965 年 1 月 24 日)是英国政治家和政治家,以在第二次世界大战期间领导英国而闻名。他被广泛认为是战时最伟大的领导人之一,曾两次担任总理。丘吉尔是一位著名的政治家和演说家,也是英国陆军军官、历史学家、作家和艺术家。

my_string_1 = '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.'
first_sentence_1 =  get_first_sentence(my_string_1)

结果:

>>> 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.'

示例 2:

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

结果:

>>> first_sentence_2
'Python is a general-purpose, high-level programming language[11] whose design philosophy emphasizes code readability.'

示例 3:

中国(Listeni/ˈtʃaɪnə/;中文:中国;拼音:Zhōngguó;另见中国名称),正式名称为中华人民共和国(PRC),是世界上人口最多的国家,人口超过 13 亿。东亚国家占地约 960 万平方公里,是世界上陆地面积第二大的国家,[13] 根据总面积的定义,其总面积位居第三或第四大国家。 [14]

my_string_3 = "China (Listeni/ˈtʃaɪnə/; Chinese: 中国; pinyin: Zhōngguó; 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 billion. Covering approximately 9.6 million square kilometres, the East Asian state is the world's second-largest country by land area,[13] and the third- or fourth-largest in total area, depending on the definition of total area.[14]"
first_sentence_3 = get_first_sentence(my_string_3)

结果:

>>> 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 中。

此外,使用正则表达式可能会更好地完成上述操作。

只是一个想法。

于 2012-06-18T17:41:39.893 回答
0

虽然这里很多人都有优点,但自然语言处理实际上是一项非常艰巨的任务,并且已经对其进行了大量研究,但结果非常不可靠。但是,那里有解决方案。很多人都提到了自然语言工具包,它是现存最强大的自然语言处理工具之一。NLTK 确实有一个现成的句子标记器,虽然它并不完美,但它非常好。它被称为 PunktSentenceTokenizer,它可以很好地过滤缩写词。对于更多的俚语来说,它有很多麻烦,但对于像你上面这样的小说来说,它的效果非常好。文档可以在这里找到:http: //nltk.googlecode.com/svn/trunk/doc/api/nltk.tokenize.punkt.PunktSentenceTokenizer-class.html

from nltk import tokenize

def print_sentences(text):
    test = tokenize.punkt.PunktSentenceTokenizer()
    return test.sentences_from_text(text)

可悲的是,它实际上不适用于您提出的示例,但它确实有一个非常详细的查找并且它捕获了很多缩写。我认为这个例子的大部分项目是“Hon”。也是一个专有名词,字典可能会这样看。可以在 nltk 中自定义配置您的字典以捕捉这种特殊情况,就像在 fraxel 的回答中一样,简单的标记器不会捕捉到 punkt 标记器将捕捉到的许多其他缩写、价格符号或其他此类常见情况。

于 2012-06-18T20:42:26.283 回答
-1

如果您坚持一个惯例,即句号仅在其后跟一个空格或换行符时才结束一个句子,您可以执行以下操作:

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]
于 2012-09-14T21:27:57.893 回答