Ayrı kelimelerle bir cümle bölünmüş

11 Cevap php

Ayrı bir deyişle bir Çinli cümle bölmek gerekir. Çin ile sorun boşluk olmasıdır. 主楼怎么走 (boşluklarla olurdu: 主楼 怎么 走) Örneğin, cümle gibi görünebilir.

Şu anda ben bir çözüm düşünebilirsiniz. Ben (bir veritabanı) Çince kelimelerle bir sözlük var. Olacak komut dosyası:

  1. veritabanında cümlenin ilk iki karakterleri bulmak için çalışın (主楼),

  2. 主楼 aslında bir kelime ve veritabanında varsa komut ilk üç karakterini bulmaya çalışacağız (主楼怎). 主楼怎 bir kelime değil, bu yüzden şimdi veritabanı => Benim uygulamada değil 主楼, ayrı bir kelime olduğunu biliyor.

  3. karakter geri kalanı ile bunu deneyin.

Bu veritabanını çok kez sorgulamak istiyorum hatta küçük bir metni analiz etmek, çünkü ben gerçekten bu yaklaşım sevmiyorum.

Bu başka bir çözüm var mı?

11 Cevap

Yardım için herkese teşekkürler!

Biraz araştırma yaptıktan sonra (akılda tüm önerilerinizi olan) bazı çalışma araçları buldum ben kendi soru cevap veriyorum, neden budur.

  1. Bir PHP sınıfı (http://www.phpclasses.org/browse/package/2431.html)

  2. Bir Drupal modülü, 4 farklı algoritmaların (oldukça kolay nasıl çalıştığını anlamak için) ile temel olarak başka bir PHP çözüm (http://drupal.org/project/csplitter)

  3. Çince kelime segmentasyon için bir PHP uzantısı (http://code.google.com/p/phpcws/)

  4. Sizin için baidu.com aramayı deneyin eğer Mevcut diğer bazı çözümler "中文 分 词 vardır"

Saygılarımızla,

Equ

Bir trie veri yapısını kullanarak düşünebilirsiniz. Önce sonra geçerli kelime ararken çok daha hızlı olacaktır sözlükten traydan inşa. Bir kelimenin sonunda veya daha uzun kelimeler için aramaya devam gereken çok hızlı ise avantaj belirlemektir.

Sen giriş metni, cümle, paragraf ne var. Yani evet, o sizin işlem need her onay için DB sorgulamak için olacaktır.

Olsa sözcük sütun üzerinde iyi indeksleme ile, çok fazla sorun olmamalıdır.

Bu sözlük ne kadar büyük olduğunu söyledi? Tüm bunlardan sonra, sadece geçerli bir kelime olup olmadığını kontrol etmek için onların tanımları, kelimeleri değil gerekir. Yani mümkünse (boyutuna bağlı olarak), sadece tuşları (fiili kelime) ile büyük bir bellek haritası / hashtable / sözlük sahip bir seçenek olabilir ve şimşek gibi hızlı olurdu.

15 million sözcüklerde, ortalama 7 karakter söylüyor @ 2 bytes, her 200 megabayt işareti etrafında çalışır. Çok deli değil.

Edit: 'sadece' 1 milyon kelime, sen etrafında sadece üzerinde 13 megabayt bakıyoruz, 15 bazı yüküyle söylüyorlar. Yani diyorum ki, bir no-beyin bulunuyor.

Iyi çalışan başka biri http://www.itgrass.com/phpanalysis/index.html

Utf-8 ile düzgün çalışır buldum Onun tek. Gerisi sadece daha sonra satır aşağı sorunları ton neden olan, GB18030 benim için çalıştı. Ben baştan başlamak zorunda olacak sanıyordum, ama bu bana çok zaman kurtardı.

Tüm kelimelerle bir veritabanı var ve katılanların kelime almak için başka bir yolu varsa Eh, ben yeniden sorgu veritabanı zorunda düşünüyorum.

Bu performansını artırmak için, size veritabanına cümle eklemeden önce tüm bu kontrolleri yapmak ve boşluk kendinizi ekleyemiyorum?

(ABCDE basitlik için Çince karakterler temsil etmek için kullanarak)

AB, {[(3)]: Diyelim ki 'cümlesini' ABCDE giriş var, ve sözlük A ile başlar, bu sözcükleri içeren diyelim }, AC, AE ve ABB. Ve kelime CDE var, ama DE tahmin, ne de E yok.

Sağa sola gidiyor giriş cümle, ayrıştırma, komut ilk karakteri çeker A. Bunun yerine A bir kelime ise ile başlayan tüm kelimeleri çekmek için veritabanını sorgulamak, görmek için veritabanı sorgulama A.

Uygun bir karşılaştırma almak için giriş dizeden önümüzdeki birkaç karakteri kapma bu sonuçları döngü:

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

Bu noktada iki 'gerçek' şube aşağı programı çatal buldum. Ilk günü, bu AB ilk kelime varsayar, ve C bulmak için başlayan kelimeleri dener. CDE bulunmuş, bu yüzden bu dal meydana gelmesi mümkündür. Diğer şube aşağı, ABC ilk kelime, ama DE mümkün değildir, böylece şube ilk gerçek yorumlanması olmalıdır anlamı, geçersiz.

Ben (kelimelerin setleri hepsi aynı karakteri ile başlayan getiriliyor konum gibi, veritabanından daha büyük kümeleri döndürebilir olsa) bu yöntemi veritabanına çağrıların sayısını minimize düşünüyorum. Veritabanı arama için bu tür endeksli olsaydı, ben bu mektubu yazmak-giderek daha iyi çalıştığını düşünüyorum. Şimdi bütün bu süreçte, ve diğer cevaplara baktığımızda, başka bir afiş söylediği gibi bu, aslında (karakter bir ağacın kök aramış varsayarak) bir tray yapısı olduğunu düşünüyorum. Peki, burada bu fikri bir uygulama var!

Bu bilişimsel dilbilim oldukça standart bir iştir. Bu isim "simgelileştirme" ya gider "kelimesi segmentasyon." "Çince kelime segmentasyon" veya "çince simgelileştirme" için arama yapmayı deneyin ve bunu yapmak için birkaç bu görevi yapmak için yapılmış araçları, yanı sıra araştırma sistemleri hakkında kağıtları bulabilirsiniz.

De bunu yapmak için, genellikle oldukça büyük bir eğitim korpus bir makine öğrenme sistemi çalıştıran tarafından inşa istatistiksel bir model kullanmak gerekecektir. Eğer internet üzerinde bulabileceğiniz sistemlerinin birkaç öncesi eğitim modelleri ile geliyor.

Ben çince kelime segmentasyon sorun çok karmaşık biri olduğunu fark yoktur, ancak bazı durumlarda bu önemsiz algoritma yeterli olabilir:, sonra i + uzunluk (w) inci karakter için yeniden başlamak i'inci karakteri ile başlayan w uzun sözcüğü arama .

Burada bir Python uygulaması bulunuyor:

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

Son bölümü bir kopyasını kullanır CCEDICT dictionary segmente (sözcük olmayan karakterler ile ve olmadan sırasıyla,,) iki tatlar bir (basitleştirilmiş) Çince metni:

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

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

Bölüm Çince metin için iyi ve hızlı bir şekilde temelde segmentasyon kombinasyonu en muhtemel olduğu görmek için kelimelerin farklı uzunluk test edecek olan maksimum Eşleştirme segmentasyonu dayanmaktadır. Bunu yapmak için mümkün olan tüm kelimelerin bir listesini alır.

Burada bu konuda daha fazla bilgi: http://technology.chtsai.org/mmseg/

O benim 读者 (Duzhe) Metin Analyzer kullanmak yöntem (http://duzhe.aaginskiy.com). Ben aslında RAM ~ 2MB yaklaşık sürebilir yapar bir diziye kelimelerin bir listesini önceden yükleyecektir, bir veritabanı kullanmak, ancak çok hızlı yürütür yok.

(Istatistiksel yöntem bazı araştırmalara göre% 97 ~ olarak doğru olabilir ama) istatistiki fazla sözcük kullanarak segment içine arıyorsanız, çok iyi bir bölümlendirme aracı burada bulabilirsiniz ADSOtrans olduğunu:

http://www.adsotrans.com

Bu bir veritabanı kullanır ama segmentasyonu hızlandırmak için gereksiz bir sürü tablolar vardır. Ayrıca segmentasyon yardımcı gramer tanımları sağlayabilir.

Umarım bu yardımcı olur.

Sen çok çok uzun Düzenli İfade inşa edebilirsiniz.

Edit: I meant to build it automatically with script from the DB. Not to write it by hand.