Разделить предложение на отдельные слова
Мне нужно разделить китайское предложение на отдельные слова. Проблема с китайцами в том, что нет пробелов. Например, предложение может выглядеть так: 主楼怎么走
(с пробелами: 主楼 怎么 走
).
На данный момент я могу думать о одном решении. У меня есть словарь с китайскими словами (в базе данных). script будет:
-
попытайтесь найти первые два символа предложения в базе данных (主楼
),
-
если 主楼
на самом деле является словом, а в базе данных script будет пытаться найти первые три символа (主楼怎
). 主楼怎
не является словом, поэтому он не находится в базе данных = > теперь мое приложение знает, что 主楼
- это отдельное слово.
-
попробуйте сделать это с остальными символами.
Мне не нравится этот подход, потому что для анализа даже небольшого текста он будет запрашивать базу данных слишком много раз.
Есть ли другие решения?
Ответы
Ответ 1
Спасибо всем за помощь!
После небольшого исследования я нашел некоторые рабочие инструменты (имея в виду все ваши предложения), поэтому я отвечаю на свой вопрос.
С уважением,
Equ
Ответ 2
Возможно, вам захочется использовать структуру данных trie. Сначала вы строите trie из словаря, тогда поиск правильных слов будет намного быстрее. Преимущество заключается в определении того, находитесь ли вы в конце слова или хотите продолжить поиск более длинных слов очень быстро.
Ответ 3
У вас есть входной текст, предложение, пункт что угодно. Так что да, ваша обработка будет необходима для запроса к вашей БД для каждой проверки.
При достойном индексировании столбца слова, у вас не должно быть слишком много проблем.
Сказав это, насколько велик этот словарь? В конце концов, вам понадобятся только слова, а не их определения, чтобы проверить, действительно ли это слово. Поэтому, если это вообще возможно (в зависимости от размера), наличие огромной карты памяти/хеш-таблицы/словаря с помощью только клавиш (фактические слова) может быть опцией и будет быстрой, как молния.
В словах 15 миллионов, скажем, в среднем 7 символов @ 2 байта, каждый из них работает вокруг отметки 200 мегабайт. Не слишком сумасшедший.
Изменить: В "только" 1 миллион слов вы просматриваете чуть более 13 мегабайт, скажем, 15 с некоторыми накладными расходами. Я бы сказал, что это не проблема.
Ответ 4
Другой, который хорошо работает, http://www.itgrass.com/phpanalysis/index.html
Это единственное, что я нашел, что правильно работает с utf-8. Остальное работало только для меня в gb18030, что вызвало массу проблем позже. Я думал, что мне придется начать все сначала, но это спасло меня много времени.
Ответ 5
Хорошо, если у вас есть база данных со всеми словами, и нет другого способа привлечь это слово, я думаю, вы вынуждены повторно запрашивать базу данных.
Ответ 6
Чтобы повысить производительность этого процесса, не можете ли вы выполнить все эти проверки перед тем, как вставить предложение в базу данных и самостоятельно добавить пробелы?
Ответ 7
(используя ABCDE, чтобы представлять китайские символы для простоты)
Скажем, у вас есть вход "предложение" ABCDE, и ваш словарь содержит эти слова, начинающиеся с A: AB, ABC, AC, AE и ABB. И предположим, что существует слово CDE, но DE, а не E.
При анализе входного предложения, идущего влево-вправо, script вытаскивает первый символ A. Вместо запроса базы данных, чтобы узнать, является ли A слово, запросите базу данных, чтобы вытащить все слова, начинающиеся с A.
Прокрутите эти результаты, захватив следующие несколько символов из входной строки, чтобы получить правильное сравнение:
AB ?= AB : True
ABC ?= ABC: True
AC ?= AB : False
AE ?= AB : False
ABB ?= ABC: False
В этот момент программа распаковывает две "истинные" ветки, найденные ею. Во-первых, он предполагает, что AB является первым словом и пытается найти слова C. CDE, поэтому возможна ветка. В другой ветке ABC - это первое слово, но DE невозможно, поэтому ветвь недействительна, что означает, что первая должна быть истинной интерпретацией.
Я думаю, что этот метод минимизировал количество вызовов в базе данных (хотя он мог бы возвращать более крупные наборы из базы данных, поскольку вы извлекаете множество слов, начинающихся с одного и того же символа). Если ваша база данных была проиндексирована для такого рода поиска, я думаю, что это будет работать лучше, чем письмо с письмом. Теперь, глядя на весь этот процесс, и на другие ответы, я думаю, что это фактически структура trie (предполагая, что искаженный персонаж является корнем дерева), как предложил другой плакат. Ну, вот реализация этой идеи!
Ответ 8
Я понимаю, что проблема сегментации китайского слова является очень сложной, но в некоторых случаях этот тривиальный алгоритм может быть достаточным: найдите самое длинное слово w, начинающееся с i-го символа, затем снова запустите для длины я + (w ) -го символа.
Здесь реализована реализация Python:
#!/usr/bin/env python
# encoding: utf-8
import re
import unicodedata
import codecs
class ChineseDict:
def __init__(self,lines,rex):
self.words = set(rex.match(line).group(1) for line in lines if not line.startswith("#"))
self.maxWordLength = max(map(len,self.words))
def segmentation(self,text):
result = []
previousIsSticky = False
i = 0
while i < len(text):
for j in range(i+self.maxWordLength,i,-1):
s = text[i:j]
if s in self.words:
break
sticky = len(s)==1 and unicodedata.category(s)!="Lo"
if previousIsSticky or (result and sticky):
result[-1] += s
else:
result.append(s)
previousIsSticky = sticky
i = j
return u" | ".join(result)
def genWords(self,text):
i = 0
while i < len(text):
for j in range(i+self.maxWordLength,i,-1):
s = text[i:j]
if s in self.words:
yield s
break
i = j
if __name__=="__main__":
cedict = ChineseDict(codecs.open("cedict_ts.u8",'r','utf-8'),re.compile(r"(?u)^.+? (.+?) .+"))
text = u"""33. 你可以叫我夏尔
戴高乐将军和夫人在科隆贝双教堂村过周末。星期日早晨,伊冯娜无意中走进浴室,正巧将军在洗盆浴。她感到非常意外,不禁大叫一声:"我的上帝!"
戴高乐于是转过身,看见妻子因惊魂未定而站立在门口。他继续用香皂擦身,不紧不慢地说:"伊冯娜,你知道,如果是我们之间的隐私,你可以叫我夏尔,用不着叫我上帝……"
"""
print cedict.segmentation(text)
print u" | ".join(cedict.genWords(text))
В последней части используется копия словарь CCEDICT для сегментации (упрощенного) китайского текста в двух вариантах (соответственно, с и без символов без слова):
33. 你 | 可以 | 叫 | 我 | 夏 | 尔
戴高乐 | 将军 | 和 | 夫人 | 在 | 科隆 | 贝 | 双 | 教堂 | 村 | 过 | 周末。星期日 | 早晨,伊 | 冯 | 娜 | 无意中 | 走进 | 浴室,正巧 | 将军 | 在 | 洗 | 盆浴。她 | 感到 | 非常 | 意外,不禁 | 大 | 叫 | 一声:"我的 | 上帝!"
戴高乐 | 于是 | 转 | 过 | 身,看见 | 妻子 | 因 | 惊魂 | 未定 | 而 | 站立 | 在 | 门口。他 | 继续 | 用 | 香皂 | 擦 | 身,不 | 紧 | 不 | 慢 | 地 | 说:"伊 | 冯 | 娜,你 | 知道,如果 | 是 | 我们 | 之间 | 的 | 隐私,你 | 可以 | 叫 | 我 | 夏 | 尔,用不着 | 叫 | 我 | 上帝……"
你 | 可以 | 叫 | 我 | 夏 | 尔 | 戴高乐 | 将军 | 和 | 夫人 | 在 | 科隆 | 贝 | 双 | 教堂 | 村 | 过 | 周末 | 星期日 | 早晨 | 伊 | 冯 | 娜 | 无意中 | 走进 | 浴室 | 正巧 | 将军 | 在 | 洗 | 盆浴 | 她 | 感到 | 非常 | 意外 | 不禁 | 大 | 叫 | 一声 | 我的 | 上帝 | 戴高乐 | 于是 | 转 | 过 | 身 | 看见 | 妻子 | 因 | 惊魂 | 未定 | 而 | 站立 | 在 | 门口 | 他 | 继续 | 用 | 香皂 | 擦 | 身 | 不 | 紧 | 不 | 慢 | 地 | 说 | 伊 | 冯 | 娜 | 你 | 知道 | 如果 | 是 | 我们 | 之间 | 的 | 隐私 | 你 | 可以 | 叫 | 我 | 夏 | 尔 | 用不着 | 叫 | 我 | 上帝
Ответ 9
Хороший и быстрый способ сегментировать китайский текст основан на максимальной согласованной сегментации, которая в основном будет проверять разную длину слов, чтобы увидеть, какая комбинация сегментации наиболее вероятна. Для этого требуется список всех возможных слов.
Подробнее об этом читайте здесь: http://technology.chtsai.org/mmseg/
То, что метод, который я использую в моем текстовом анализаторе 读者 (DuZhe) (http://duzhe.aaginskiy.com). Я не использую базу данных, на самом деле я предварительно загружаю список слов в массив, который занимает около ~ 2 МБ ОЗУ, но выполняется очень быстро.
Если вы изучаете использование лексической сегментации по статистике (хотя статистический метод может быть таким же точным, как ~ 97%, согласно некоторым исследованиям), очень хороший инструмент сегментации - это ADSOtrans, который можно найти здесь:
http://www.adsotrans.com
Он использует базу данных, но имеет множество избыточных таблиц, чтобы ускорить сегментацию. Вы также можете предоставить грамматические определения, чтобы помочь сегментации.
Надеюсь, что это поможет.
Ответ 10
Это довольно стандартная задача в вычислительной лингвистике. Это происходит под названием "токенизация" или "сегментация слов". Попробуйте найти "китайскую сегментацию слов" или "китайскую символизацию", и вы найдете несколько инструментов, которые были сделаны для выполнения этой задачи, а также документы о исследовательских системах для этого.
Чтобы сделать это хорошо, вам, как правило, потребуется использовать статистическую модель, созданную путем запуска системы машинного обучения на довольно большом учебном корпусе. Некоторые из систем, которые вы можете найти в Интернете, поставляются с предварительно подготовленными моделями.
Ответ 11
Вы можете создать очень длинное регулярное выражение.
Edit:
Я хотел создать его автоматически с помощью script из БД. Не писать
рука.