【nlp】正向最大匹配算法、逆向最大匹配算法、双向最大匹配算法代码实现

from collections import defaultdict
‘‘‘
最大匹配算法 Maximum Match
{
    正向最大匹配,
    逆向最大匹配,
    双向最大匹配;

    分词算法设计中的几个基本原则:
1、颗粒度越大越好:用于进行语义分析的文本分词,要求分词结果的颗粒度越大,
    即单词的字数越多,所能表示的含义越确切,如:“公安局长”可以分为“公安 局长”、“公安局 长”、“公安局长”
    都算对,但是要用于语义分析,则“公安局长”的分词结果最好(当然前提是所使用的词典中有这个词)

2、切分结果中非词典词越少越好,单字字典词数越少越好,
    这里的“非词典词”就是不包含在词典中的单字,而“单字字典词”指的是可以独立运用的单字,
    如“的”、“了”、“和”、“你”、“我”、“他”。
    例如:“技术和服务”,可以分为“技术 和服 务”以及“技术 和 服务”,
    因为“务”字无法独立成词(即词典中没有),而“和”字可以单独成词(词典中要包含),
    因此“技术 和服 务”有1个非词典词,而“技术 和 服务”有0个非词典词,因此选用后者。

3、总体词数越少越好,在相同字数的情况下,总词数越少,
    说明语义单元越少,那么相对的单个语义单元的权重会越大,因此准确性会越高。
}
‘‘‘
# 加载词典
def load_dict(path):
    word_dict = set()#创建一个去重集合
    with open(path, ‘r‘,encoding=‘UTF-8‘) as f:
        for line in f:
            word_dict.add(line.strip())#Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
    return word_dict
# 正向最大匹配算法
# 返回list[tuple(word, len)]的形式, tuple[0]为词,tuple[1]为词的长度,当长度为0时代表该词为非词典词
def MM(sentence, max_len, word_dict):
    if not sentence or sentence is None:
        raise Exception("sentence can not be empty or None")#句子不能为空  #如果引发Exception异常,后面的代码将不能执行
    result = []
    i = 0
    while i < len(sentence):
        end = i + max_len if i + max_len < len(sentence) else len(sentence)#一行表达式,真值放在if之前
        # if i + max_len < len(sentence):
        #     end = i + max_len
        # else:
        #     end = len(sentence)
        temp = sentence[i]
        index = i
        for j in range(i + 1, end + 1):
            if sentence[i:j] in word_dict:#词典分割
                temp = sentence[i:j]
                index = j
        if index == i:
            result.append((temp, 0))
            i += 1
        else:
            result.append((temp, len(temp)))
            i = index
    return result

# 逆向匹配算法
# 返回list[tuple(word, len)]的形式, tuple[0]为词,tuple[1]为词的长度,当长度为0时代表该词为非词典词
def RMM(sentence, max_len, word_dict):
    if not sentence or sentence is None:
        raise Exception("sentence can not be empty or None")
    result = []
    i = len(sentence) - 1
    while i >= 0:
        start = i - max_len + 1 if i - max_len + 1 > 0 else 0
        temp = sentence[i]
        index = i
        for j in range(start, i + 1):
            if sentence[j:i+1] in word_dict:
                temp = sentence[j:i+1]
                index = j - 1
                break
        if index == i:
            result.append((temp, 0))
            i -= 1
        else:
            result.append((temp, len(temp)))
            i = index
    result.reverse()
    return result

# 双向最大匹配
# 根据大颗粒度词越多越好,非词典词和单字词越少越好原则
def BMM(sentence, max_len, word_dict):
    if not sentence or sentence is None:
        raise Exception("sentence can not be empty or None")
    foward_result = MM(sentence, max_len, word_dict)
    backward_result = RMM(sentence, max_len, word_dict)
    def count_result(result):
        counter = defaultdict(int)
        for r in result:
            if r[1] == 0:
                counter[‘OOV‘] += 1#非词典单词
               # print(counter)
            elif r[1] == 1:
                counter[‘single‘] += 1#单字词
                #print(counter)
            else:
                counter[‘multi‘] += r[1]#多字词的字数
               # print(counter)
        return counter[‘multi‘] - counter[‘OOV‘] - counter[‘single‘]
        print(counter)
    foward_count = count_result(foward_result)
    backward_count = count_result(backward_result)
    if foward_count > backward_count:
        return foward_result
    else:
        return backward_result

path = ‘./data/dict.txt‘
max_len = 3#最长的词为  中华人民共和国  共7个字
word_dict = load_dict(path)
result = MM(‘我们在野生动物园玩。‘, max_len, word_dict)
print(result)
result = RMM(‘我们在野生动物园玩。‘, max_len, word_dict)
print(result)
result = BMM(‘我们在野生动物园玩‘, max_len, word_dict)
print(result)

词典随便下载,路径对了就行。(path=‘./data/dict.txt‘)

一起学NLP,练着玩玩!

原文地址:https://www.cnblogs.com/destiny-2015/p/12013227.html

时间: 2024-07-29 08:09:16

【nlp】正向最大匹配算法、逆向最大匹配算法、双向最大匹配算法代码实现的相关文章

ios代理的使用,正向传值,逆向传值

#import <UIKit/UIKit.h> #import "SubViewController.h" @interface ViewController : UIViewController<SubViewControllerDelegate> @end #import "ViewController.h" @interface ViewController () { SubViewController *_subViewControl

暗黑3逆向分析走路CALL特征码与代码编写

//寻路 typedef struct _Move_Struct { float x; float y; float z; ULONG MapId; //? }Move_Struct, *PMove_Struct; void MoveToCoord(float x, float y, float z) { __try { Move_Struct Move = {0}; Move.x = x; Move.y = y; Move.z = z; __asm { mov eax, dwCoordBase

Android逆向 Android Studio动态调试smali代码

工具: Android Studio版本: 3.0.1 smalidea插件: https://github.com/JesusFreke/smali/wiki/smalidea. 反编译工具:本节先用Android Killer,后面介绍apktool. 一 配置插件 下载smalidea插件,然后打卡Android Studio,点击File->Setting->Plugins->Install plugin from disk,选择下载的smalidea.zip文件,安装成功后显示

自然语言处理NLP(一)

NLP 自然语言:指一种随着社会发展而自然演化的语言,即人们日常交流所使用的语言: 自然语言处理:通过技术手段,使用计算机对自然语言进行各种操作的一个学科: NLP研究的内容 词意消歧: 指代理解: 自动生成语言: 机器翻译: 人机对话系统: 文本含义识别: NLP处理 语料读入 网络 本地 分词 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018-9-28 22:21 # @Author : Manu # @Site : #

中文分词原理及工具

原理 中文分词,即 Chinese Word Segmentation,即将一个汉字序列进行切分,得到一个个单独的词.表面上看,分词其实就是那么回事,但分词效果好不好对信息检索.实验结果还是有很大影响的,同时分词的背后其实是涉及各种各样的算法的. 中文分词与英文分词有很大的不同,对英文而言,一个单词就是一个词,而汉语是以字为基本的书写单位,词语之间没有明显的区分标记,需要人为切分.根据其特点,可以把分词算法分为四大类: 基于规则的分词方法 基于统计的分词方法 基于语义的分词方法 基于理解的分词方

分词算法-正向最大匹配算法与逆向最大匹配算法

这两种分词方法都是机械分词方法,按照一定的策略将待分析的汉字串与机器词典中的词条进行匹配,若在词典中找到某个字符串,则匹配成功.按照扫描方向的不同,串匹配分词方法可以分为正向匹配和逆向匹配.按照不同长度优先匹配的情况,可以分为最大匹配和最小匹配.由于汉语单字成词的特点,正向最小匹配和逆向最小匹配一般很少用.一般说来,逆向匹配的切分精度略高于正向匹配,遇到的歧义现象也较少.统计结果表明,单纯使用正向最大匹配的错误率为1/169,单纯使用逆向最大匹配的错误率为1/245.但这种精度还远远不能满足实际

C++泛型指针的正向与逆向循环读取的改进方法

#include "stdafx.h"#include <algorithm>#include <functional>#include <vector>#include <iterator> using namespace std;int _tmain(int argc, _TCHAR* argv[]){    //双向访问的例子    char st[11] = "abcdefghij";    vector<

正向_逆向匹配分词

# 1.统计分词词典,确定词典中最长词条的字符m:# 2.从左向右取待切分语句的m个字符作为匹配字段,查找词典,如果匹配成功,则作为一个切分后的词语,# 否则,去掉待匹配字符的最后一个继续查找词典,重复上述步骤直到切分出所有词语. dictA = ['南京市', '南京市长', '长江大桥', '大桥'] maxDictA = max([len(word) for word in dictA]) sentence = "南京市长江大桥" def cutA(sentence): resu

朴素和KMP模式匹配算法(Java)

朴素模式匹配算法 public class Test { //朴素模式匹配算法 public int Index(String s,String t,int pos){ int i = pos;//主串中第几个位置开始比较 int j = 0;//模式串中的第一个位置 while(i<s.length()&&j<t.length()){ if(s.charAt(i)==t.charAt(j)){ i++; j++; }else { i = i-j+1;//主串的下一个位置 j