Beispiel #1
0
    def __parseImpl(self, text):
        length = len(text)
        nodesAry = [None] * (length + 1)
        nodesAry[0] = Tagger.__BOS_NODES

        wdc = self.wdc
        unk = self.unk
        fn = MakeLattice(nodesAry, self.setMincostNode)
        for i in range(0, length):
            if nodesAry[i] != None:
                fn.set(i)
                wdc.search(text, i, fn)       # 単語辞書から形態素を検索
                unk.search(text, i, wdc, fn)  # 未知語辞書から形態素を検索

        cur = self.setMincostNode(ViterbiNode.makeBOSEOS(),
                                  nodesAry[length]).prev

        # reverse
        head = None
        while cur.prev:
            tmp = cur.prev
            cur.prev = head
            head = cur
            cur = tmp
        return head
Beispiel #2
0
    def __parseImpl(self, text):
        length = len(text)
        nodesAry = []

        nodesAry.append(Tagger.__BOS_NODES)
        for i in range(0, length):
            nodesAry.append([])
        for i in range(0, length):
            perResult = []
            if len(nodesAry[i]):
                self.wdc.search(text, i, perResult)       # 単語辞書から形態素を検索
                self.unk.search(text, i, self.wdc, perResult)  # 未知語辞書から形態素を検索
                prevs = nodesAry[i]
                for j in range(0, len(perResult)):
                    vn = perResult[j]
                    if vn.isSpace:
                        (nodesAry[i + vn.length]).extend(prevs)
                    else:
                        (nodesAry[i + vn.length]).append(self.setMincostNode(vn, prevs))
        cur = self.setMincostNode(ViterbiNode.makeBOSEOS(), nodesAry[length]).prev

        # reverse
        head = None
        while cur.prev:
            tmp = cur.prev
            cur.prev = head
            head = cur
            cur = tmp
        return head
Beispiel #3
0
    def __parseImpl(self, text):
        text = array.array('H', UTF16Codec.encode(text)[0])
        length = len(text)
        nodesAry = [None] * (length + 1)
        nodesAry[0] = Tagger.__BOS_NODES

        wdc = self.wdc
        unk = self.unk
        fn = MakeLattice(nodesAry, self.setMincostNode)
        for i in range(0, length):
            if nodesAry[i] is not None:
                fn.set(i)
                wdc.search(text, i, fn)  # 単語辞書から形態素を検索
                unk.search(text, i, wdc, fn)  # 未知語辞書から形態素を検索

        cur = self.setMincostNode(ViterbiNode.makeBOSEOS(),
                                  nodesAry[length]).prev

        # reverse
        head = None
        while cur.prev:
            tmp = cur.prev
            cur.prev = head
            head = cur
            cur = tmp
        return head
Beispiel #4
0
    def __parseImpl(self, text):
        length = len(text)
        nodesAry = []
        nodesAry.append(Tagger.__BOS_NODES)
        for i in range(0, length):
            nodesAry.append([])

        wdc = self.wdc
        unk = self.unk
        fn = MakeLattice(nodesAry, self.setMincostNode)
        for i in range(0, length):
            if len(nodesAry[i]):
                fn.set(i)
                wdc.search(text, i, fn)  # 単語辞書から形態素を検索
                unk.search(text, i, wdc, fn)  # 未知語辞書から形態素を検索

        cur = self.setMincostNode(ViterbiNode.makeBOSEOS(),
                                  nodesAry[length]).prev

        # reverse
        head = None
        while cur.prev:
            tmp = cur.prev
            cur.prev = head
            head = cur
            cur = tmp
        return head
Beispiel #5
0
class Tagger:
    """
    形態素解析を行うクラス
    """
    __BOS_NODES = [ViterbiNode.makeBOSEOS()]

    @staticmethod
    def lookup():
        """
        モジュールが置いてある場所から辞書を探す
        @return: モジュール内で見つかった辞書のパス
        """
        path = os.path.join(abspath(dirname(__file__)), 'dic')
        if (os.path.exists(path)):
            return path
        return None

    def __init__(self, dataDir=None, gae=False):
        """
        バイナリ辞書を読み込んで、形態素解析器のインスタンスを作成する

        @param dataDir バイナリ辞書があるディレクトリ
        @throws FileNotFoundException 間f違ったディレクトリが指定された場合に送出される
        @throws IOException その他の入出力エラーが発生した場合に送出される
        """
        if not dataDir:
            dataDir = Tagger.lookup()
        self.wdc = WordDic(dataDir, gae, gae)
        self.unk = Unknown(dataDir, gae)
        self.mtx = Matrix(dataDir, gae)

    def parse(self, text, result=None):
        """
        形態素解析を行う

        @param text 解析対象テキスト
        @param result 解析結果の形態素が追加されるリスト. None指定時は内部でリストを作成する
        @return 解析結果の形態素リスト. {@code parse(text,result)=result}
        """
        if result is None:
            result = []
        vn = self.__parseImpl(text)
        wordData = self.wdc.wordData
        while vn:
            surface = text[vn.start:vn.start + vn.length]
            feature = UTF16Codec.decode(wordData(vn.wordId).tostring())[0]
            result.append(Morpheme(surface, feature, vn.start))
            vn = vn.prev
        return result

    """
    分かち書きを行う

    @param text 分かち書きされるテキスト
    @param result 分かち書き結果の文字列が追加されるリスト. None指定時は内部でリストを作成する
    @return 分かち書きされた文字列のリスト. {@code wakati(text,result)=result}
    """

    def wakati(self, text, result=None):
        if result is None:
            result = []
        vn = self.__parseImpl(text)
        while vn:
            result.append(text[vn.start:vn.start + vn.length])
            vn = vn.prev
        return result

    def __parseImpl(self, text):
        text = array.array('H', UTF16Codec.encode(text)[0])
        length = len(text)
        nodesAry = [None] * (length + 1)
        nodesAry[0] = Tagger.__BOS_NODES

        wdc = self.wdc
        unk = self.unk
        fn = MakeLattice(nodesAry, self.setMincostNode)
        for i in range(0, length):
            if nodesAry[i] is not None:
                fn.set(i)
                wdc.search(text, i, fn)  # 単語辞書から形態素を検索
                unk.search(text, i, wdc, fn)  # 未知語辞書から形態素を検索

        cur = self.setMincostNode(ViterbiNode.makeBOSEOS(),
                                  nodesAry[length]).prev

        # reverse
        head = None
        while cur.prev:
            tmp = cur.prev
            cur.prev = head
            head = cur
            cur = tmp
        return head

    def setMincostNode(self, vn, prevs):
        mtx = self.mtx
        leftId = vn.leftId
        f = vn.prev = prevs[0]
        minCost = f.cost + mtx.linkCost(f.rightId, leftId)

        for i in range(1, len(prevs)):
            p = prevs[i]
            cost = p.cost + mtx.linkCost(p.rightId, leftId)
            if cost < minCost:
                minCost = cost
                vn.prev = p

        vn.cost += minCost
        return vn