2010-01-26 12 views
13

मुझे एक चीनी वाक्य को अलग शब्दों में विभाजित करने की आवश्यकता है। चीनी के साथ समस्या यह है कि कोई रिक्त स्थान नहीं है। उदाहरण के लिए, वाक्य इस तरह दिखेगा: 主楼怎么走 (रिक्त स्थान के साथ यह होगा: 主楼 怎么 走)।एक वाक्य को अलग शब्दों में विभाजित करें

फिलहाल मैं एक समाधान के बारे में सोच सकते हैं। मेरे पास चीनी शब्द (डेटाबेस में) के साथ एक शब्दकोश है। स्क्रिप्ट करेंगे:

  1. कोशिश डेटाबेस (主楼) में वाक्य के पहले दो अक्षर लगता है,

  2. अगर 主楼 वास्तव में एक शब्द है और यह डेटाबेस स्क्रिप्ट की तलाश करेगा में है पहले तीन अक्षर (主楼怎)। 主楼怎 कोई शब्द नहीं है, इसलिए यह डेटाबेस में नहीं है => मेरा एप्लिकेशन अब जानता है कि 主楼 एक अलग शब्द है।

  3. कोशिश पात्रों के बाकी के साथ करते हैं।

मुझे यह दृष्टिकोण वास्तव में पसंद नहीं है, क्योंकि एक छोटे से पाठ का विश्लेषण करने के लिए यह डेटाबेस को कई बार पूछताछ करेगा।

क्या इसके कोई अन्य समाधान हैं?

+0

चीनी में कोई जगह नहीं होने पर बस जिज्ञासा है, आपको उन्हें * स्पेस के साथ * प्रदर्शित करने की आवश्यकता क्यों है? यहां उपयोग का मामला क्या है? हम्म - क्षमा करें, फिर से प्रश्न पढ़ें, स्पष्ट रूप से कुछ शब्द शब्दकोश लुकअप, कभी भी ध्यान न दें। –

+0

विम का कहना है कि, यदि यह लाइन-रैपिंग के उद्देश्य के लिए है, तो परेशान न करें: जहां तक ​​मुझे पता है, आप किसी भी चरित्र पर अपनी लाइन को लपेट सकते हैं। –

+0

एप्लिकेशन को अलग-अलग शब्दों को खोजने और उन्हें पिनयिन (चीनी प्रतिलेखन) प्रदान करने की आवश्यकता है। – Peterim

उत्तर

6

आपकी मदद के लिए सभी को धन्यवाद!

थोड़ा सा शोध करने के बाद मुझे कुछ काम करने वाले टूल मिल गए हैं (आपके सभी सुझावों को ध्यान में रखते हुए), यही कारण है कि मैं अपने स्वयं के प्रश्न का उत्तर दे रहा हूं।

  1. एक PHP वर्ग (http://www.phpclasses.org/browse/package/2431.html)

  2. एक Drupal मॉड्यूल, 4 अलग विभाजन एल्गोरिदम के साथ मूल रूप से एक और पीएचपी समाधान (बहुत आसान समझने के लिए यह कैसे काम करता) (http://drupal.org/project/csplitter)

  3. एक PHP चीनी शब्द विभाजन के लिए विस्तार (http://code.google.com/p/phpcws/)

  4. यदि आप baidu.com को खोजने का प्रयास करते हैं तो कुछ अन्य समाधान उपलब्ध हैं "中分 词 "

निष्ठा से

,

Equ

0

ठीक है, आप सभी शब्दों के साथ एक डेटाबेस है और वहाँ जो शब्द शामिल मुझे लगता है कि आप डेटाबेस फिर से क्वेरी करने के लिए मजबूर होना पड़ता है पाने के लिए कोई दूसरा रास्ता नहीं है अगर।

-3

तुम बहुत बहुत लंबे समय नियमित अभिव्यक्ति बना सकते हैं।

संपादित करें: मेरा मतलब डीबी से स्क्रिप्ट के साथ स्वचालित रूप से बनाना था। इसे हाथ से नहीं लिखना है।

+0

आपको क्या लगता है कि रेगेक्स एक पूर्ण शब्दकोश फ़िल्टर करने जैसा दिखता है ?? – Younes

+1

@Younes: बहुत लंबा? ... और बदसूरत – blank

+1

इस समस्या को हल करने के लिए एक रेगेक्स का उपयोग करना एक बकवास है – Eineki

2

आप एक trie डेटा संरचना के उपयोग पर विचार करना चाह सकते हैं। आप पहले शब्दकोष से त्रिभुज का निर्माण करते हैं, फिर वैध शब्दों की खोज करना बहुत तेज़ होगा। लाभ यह निर्धारित कर रहा है कि क्या आप किसी शब्द के अंत में हैं या लंबे शब्दों की तलाश जारी रखने की आवश्यकता है।

+0

इसे रेगेक्स के रूप में भी लागू किया जा सकता है (आप जानते हैं: ऑटोमाटा, परिमित राज्य मशीन, नियमित भाषा इत्यादि)। संकलन के बाद, रेगेक्स के अधिकांश कार्यान्वयन के प्रकार का परीक्षण होगा। –

+3

@ वाई। शोहम: कुछ कहते हैं कि रेगेक्स आपको सुबह टोस्ट बनाता है। –

1

आप इनपुट पाठ, वाक्य, पैराग्राफ जो कुछ भी किया है। तो हाँ, आपकी जांच के लिए आपके डीबी के खिलाफ पूछताछ के लिए की आवश्यकता होगी।

हालांकि शब्द कॉलम पर सभ्य अनुक्रमण के साथ, आपको बहुत सी समस्याएं नहीं होनी चाहिए।

यह कहकर कि, यह शब्दकोश कितना बड़ा है? आखिरकार, आपको केवल शब्दों की आवश्यकता होगी, न कि उनकी परिभाषा यह जांचने के लिए कि यह वैध शब्द है या नहीं। तो यदि संभव हो तो (आकार के आधार पर), जिसमें केवल कुंजी (वास्तविक शब्द) के साथ एक विशाल मेमोरी मैप/हैशटेबल/डिक्शनरी होना एक विकल्प हो सकता है और बिजली के रूप में तेज़ होगा।

15 दस लाख शब्द में कहना औसत 7 वर्ण @2 बाइट्स प्रत्येक 200 मेगाबाइट निशान के आसपास बाहर काम करता है। बहुत पागल नहीं है।

संपादित करें: 'केवल' 1 मिलियन शब्दों पर, आप लगभग 13 मेगाबाइट्स के आसपास देख रहे हैं, 15 ओवरहेड के साथ 15 कहें। यह एक ब्रेनर है जो मैं कहूंगा।

+0

इस समय केवल 300 000 शब्द हैं, अधिकतम अधिकतम 1 मिलियन होगा। तो मुझे लगता है कि यह एक विकल्प है =) – Peterim

+0

उस स्थिति में, मैं निश्चित रूप से स्मृति में एक शब्द वस्तु में सभी शब्दों को फेंक दूंगा। –

0

इसका प्रदर्शन सुधारने के लिए, क्या आप डेटाबेस में वाक्य डालने से पहले इन सभी चेकों को नहीं कर सकते हैं, और रिक्त स्थान जोड़ सकते हैं?

+0

समस्या यह है कि चेक के लिए, आपको शब्दकोश को क्वेरी करने की आवश्यकता होगी ... बस आपको पता है कि वाक्य को तोड़ना है। –

+0

दुर्भाग्यवश, यह एप्लिकेशन द्वारा स्वचालित रूप से किया जाना चाहिए। एक उपयोगकर्ता एक वाक्य इनपुट करता है और पिनयिन के साथ अलग शब्द प्राप्त करता है। – Peterim

0

(ABCDE का उपयोग कर सादगी के लिए चीनी अक्षरों का प्रतिनिधित्व करने के लिए)

मान लीजिए कि आप 'सजा' ABCDE इनपुट मिल गया है, और अपने शब्दकोश इन शब्दों कि एक के साथ शुरू होता है दो: एबी, एबीसी, एसी, एई, और एबीबी। और मान लें कि शब्द सीडीई मौजूद है, लेकिन DE, न ही नहीं।

इनपुट वाक्य को पार्स करते समय, बाएं से दाएं जाकर, स्क्रिप्ट पहले वर्ण खींचती है। एक शब्द है, यह देखने के लिए डेटाबेस को क्वेरी करने के बजाय से शुरू होने वाले सभी शब्दों को खींचने के लिए डेटाबेस से पूछें।

AB ?= AB : True 
ABC ?= ABC: True 
AC ?= AB : False 
AE ?= AB : False 
ABB ?= ABC: False 

इस बिंदु पर दो 'सही' शाखाओं यह पाया नीचे कार्यक्रम कांटे: उन परिणामों के माध्यम से

लूप, इनपुट स्ट्रिंग से अगले कुछ पात्रों हथियाने एक उचित तुलना मिलता है। पहले, यह एबी पहला शब्द है, और सी -स्टार्टिंग शब्द खोजने का प्रयास करता है। सीडीई पाया जाता है, ताकि शाखा संभव हो। दूसरी शाखा के नीचे, एबीसी पहला शब्द है, लेकिन DE संभव नहीं है, ताकि शाखा अमान्य हो, जिसका अर्थ है कि पहला वास्तविक व्याख्या होना चाहिए।

मुझे लगता है कि इस विधि ने डेटाबेस में कॉल की संख्या को कम किया है (हालांकि यह डेटाबेस से बड़े सेट लौटा सकता है, क्योंकि आप एक ही चरित्र से शुरू होने वाले शब्दों के सेट ला रहे हैं)। यदि आपके डेटाबेस को इस प्रकार की खोज के लिए अनुक्रमित किया गया था, तो मुझे लगता है कि यह पत्र-पत्र पत्र जाने से बेहतर काम करेगा। अब इस पूरी प्रक्रिया को देखते हुए, और अन्य उत्तरों, मुझे लगता है कि यह वास्तव में एक त्रिभुज संरचना है (माना जाता है कि चरित्र की खोज एक पेड़ की जड़ है), जैसा कि एक अन्य पोस्टर ने सुझाव दिया था। खैर, यहां उस विचार का कार्यान्वयन है!

-1

यह कम्प्यूटेशनल भाषाविज्ञान में एक काफी मानक कार्य है। यह "टोकननाइजेशन" या "वर्ड सेगमेंटेशन" नाम से जाता है। "चीनी शब्द विभाजन" या "चीनी टोकननाइजेशन" की खोज करने का प्रयास करें और आपको यह कार्य करने के लिए कई टूल मिलेंगे, साथ ही अनुसंधान प्रणालियों के बारे में कागजात भी किए जाएंगे।

यह अच्छी तरह से करने के लिए, आपको आम तौर पर एक बड़े पैमाने पर प्रशिक्षण कॉर्पस पर मशीन लर्निंग सिस्टम चलाने के द्वारा बनाए गए सांख्यिकीय मॉडल का उपयोग करने की आवश्यकता होगी। वेब पर आप पाए जाने वाले कई सिस्टम प्री-प्रशिक्षित मॉडल के साथ आते हैं।

0

मुझे पता है कि चीनी शब्द विभाजन समस्या एक बहुत जटिल है, लेकिन कुछ मामलों में यह तुच्छ एल्गोरिथ्म पर्याप्त हो सकता है: सबसे लंबा शब्द खोज ith चरित्र के साथ शुरू करते हैं, फिर i + लंबाई (डब्ल्यू) वें चरित्र के लिए फिर से शुरू करें।

#!/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)) 

अंतिम भाग (के साथ या बिना गैर शब्द पात्रों resp,।) दो रूपों में खंड के लिए CCEDICT dictionary एक (सरलीकृत) चीनी पाठ की एक प्रति का उपयोग करता है:

यहाँ एक अजगर कार्यान्वयन है

33. 你 | 可以 | 叫 | 我 | 夏 | 尔 
    戴高乐 | 将军 | 和 | 夫人 | 在 | 科隆 | 贝 | 双 | 教堂 | 村 | 过 | 周末。星期日 | 早晨,伊 | 冯 | 娜 | 无意中 | 走进 | 浴室,正巧 | 将军 | 在 | 洗 | 盆浴。她 | 感到 | 非常 | 意外,不禁 | 大 | 叫 | 一声:“我的 | 上帝!” 
    戴高乐 | 于是 | 转 | 过 | 身,看见 | 妻子 | 因 | 惊魂 | 未定 | 而 | 站立 | 在 | 门口。他 | 继续 | 用 | 香皂 | 擦 | 身,不 | 紧 | 不 | 慢 | 地 | 说:“伊 | 冯 | 娜,你 | 知道,如果 | 是 | 我们 | 之间 | 的 | 隐私,你 | 可以 | 叫 | 我 | 夏 | 尔,用不着 | 叫 | 我 | 上帝……” 

你 | 可以 | 叫 | 我 | 夏 | 尔 | 戴高乐 | 将军 | 和 | 夫人 | 在 | 科隆 | 贝 | 双 | 教堂 | 村 | 过 | 周末 | 星期日 | 早晨 | 伊 | 冯 | 娜 | 无意中 | 走进 | 浴室 | 正巧 | 将军 | 在 | 洗 | 盆浴 | 她 | 感到 | 非常 | 意外 | 不禁 | 大 | 叫 | 一声 | 我的 | 上帝 | 戴高乐 | 于是 | 转 | 过 | 身 | 看见 | 妻子 | 因 | 惊魂 | 未定 | 而 | 站立 | 在 | 门口 | 他 | 继续 | 用 | 香皂 | 擦 | 身 | 不 | 紧 | 不 | 慢 | 地 | 说 | 伊 | 冯 | 娜 | 你 | 知道 | 如果 | 是 | 我们 | 之间 | 的 | 隐私 | 你 | 可以 | 叫 | 我 | 夏 | 尔 | 用不着 | 叫 | 我 | 上帝 
0

खंड चीनी पाठ करने के लिए एक अच्छा और तेज़ तरीका अधिकतम मिलान विभाजन, जो मूल रूप से है देखने के लिए जो विभाजन के संयोजन सबसे अधिक संभावना है शब्दों के विभिन्न लंबाई परीक्षण पर आधारित है। ऐसा करने के लिए सभी संभावित शब्दों की एक सूची में यह लगता है।

इसके बारे में और अधिक पढ़ें यहाँ: http://technology.chtsai.org/mmseg/

विधि मैं अपने 读者 (DuZhe) पाठ विश्लेषक (http://duzhe.aaginskiy.com) में उपयोग करते हैं यही कारण है कि। मैं डेटाबेस का उपयोग नहीं करता, असल में मैं शब्दों की एक सूची को एक सरणी में प्री-लोड करता हूं जो ~ 2 एमबी रैम लेता है, लेकिन बहुत जल्दी निष्पादित करता है।

आप सांख्यिकीय से अधिक शाब्दिक विभाजन का उपयोग करते हुए देख रहे हैं (हालांकि सांख्यिकीय गतिविधियों के कुछ शोध के अनुसार के रूप में ~ 97% के रूप में सही हो सकता है), एक बहुत अच्छा विभाजन उपकरण ADSOtrans यहां पाया जा सकता है जो:

http://www.adsotrans.com

यह डेटाबेस का उपयोग करता है लेकिन विभाजन को गति देने के लिए बहुत सी अनावश्यक तालिकाओं हैं। आप विभाजन की सहायता के लिए व्याकरण संबंधी परिभाषा भी प्रदान कर सकते हैं।

उम्मीद है कि इससे मदद मिलती है।

1

एक और एक है कि अच्छी तरह से काम करता है http://www.itgrass.com/phpanalysis/index.html

इसका केवल एक ही है कि मैंने पाया कि utf-8 के साथ ठीक से काम करता है। शेष ने केवल मेरे लिए जीबी 18030 में काम किया, जिसके कारण लाइनों के बाद कई मुद्दों का कारण बन गया। मैंने सोचा कि मुझे शुरू करना होगा, लेकिन इसने मुझे बहुत समय बचाया।

संबंधित मुद्दे