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

        @param dataDir バイナリ辞書があるディレクトリ
        @throws FileNotFoundException 間f違ったディレクトリが指定された場合に送出される
        @throws IOException その他の入出力エラーが発生した場合に送出される
        """
        self.wdc = WordDic(dataDir, gae, gae)
        self.unk = Unknown(dataDir, gae)
        self.mtx = Matrix(dataDir, gae)
示例#2
0
    def __init__(self, path=None, gae=False, use_mmap=None):
        """
        バイナリ辞書を読み込んで、形態素解析器のインスタンスを作成する

        @param path directory of a binary dictionary
        """
        if not path:
            path = Tagger.lookup()
        self.wdc = WordDic(path, gae, gae, use_mmap)
        self.unk = Unknown(path, gae, use_mmap)
        self.mtx = Matrix(path, gae, use_mmap)
示例#3
0
    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)
示例#4
0
class Tagger:
    """
    形態素解析を行うクラス
    """
    __BOS_NODES = [ViterbiNode.makeBOSEOS()]

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

        @param dataDir バイナリ辞書があるディレクトリ
        @throws FileNotFoundException 間f違ったディレクトリが指定された場合に送出される
        @throws IOException その他の入出力エラーが発生した場合に送出される
        """
        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)
        while vn:
            surface = text[vn.start:vn.start + vn.length]
            feature = u''.join([unichr(x) for x in self.wdc.wordData(vn.wordId)])
            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):
        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

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

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

        vn.cost += self.wdc.cost(vn.wordId)
        return vn
示例#5
0
class Tagger:
    """
    形態素解析を行うクラス
    """
    __slots__ = ['wdc', 'unk', 'mtx']
    __BOS_NODES = [ViterbiNode.makeBOSEOS()]

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

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

        @param path directory of a binary dictionary
        """
        if not path:
            path = Tagger.lookup()
        self.wdc = WordDic(path, gae, gae, use_mmap)
        self.unk = Unknown(path, gae, use_mmap)
        self.mtx = Matrix(path, gae, use_mmap)

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

        @param text 解析対象テキスト
        @param result 解析結果の形態素が追加されるリスト. None指定時は内部でリストを作成する
        @return 解析結果の形態素リスト. {@code parse(text,result)=result}
        """
        if result is None:
            result = []
        text = array.array('H', UTF16Codec.encode(text)[0])
        vn = self.__parse(text)
        wd = self.wdc.word_data
        while vn:
            surface = UTF16Codec.decode(text[vn.start:vn.start + vn.length])[0]
            feature = UTF16Codec.decode(wd(vn.word_id))[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 = []
        text = array.array('H', UTF16Codec.encode(text)[0])
        vn = self.__parse(text)
        while vn:
            result.append(UTF16Codec.decode(text[vn.start:vn.start +
                                                 vn.length])[0])
            vn = vn.prev
        return result

    def __parse(self, text):
        length = len(text)
        nodes = [None] * (length + 1)
        nodes[0] = Tagger.__BOS_NODES

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

        cur = self.set_mincost_node(ViterbiNode.makeBOSEOS(),
                                    nodes[length]).prev

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

    def set_mincost_node(self, vn, prevs):
        mtx = self.mtx
        left_id = vn.left_id
        f = vn.prev = prevs[0]
        mincost = f.cost + mtx.linkcost(f.right_id, left_id)

        for i in range(1, len(prevs)):
            p = prevs[i]
            cost = p.cost + mtx.linkcost(p.right_id, left_id)
            if cost < mincost:
                mincost = cost
                vn.prev = p

        vn.cost += mincost
        return vn

    def release(self):
        self.wdc.release()
        self.unk.release()
        self.mtx.release()

    def __enter__(self):
        return self

    def __exit__(self, et, ev, tb):
        self.release()