NLP实战——基于枚举实现中文分词(python)

基于枚举法的停词

逻辑:
例子:我们经常有意见分歧
词典:【“我们”,“经常”,“有”,“有意见”,“意见”,“分歧”】

枚举满足词典的所有可能情况:

  1. 我们、 经常、有、意见、分歧
  2. 我们、经常、有意见、分歧

实现所需的数据需求:

  • 中文词库,充当词典的作用
  • 以变量的方式提供了部分unigram概率 word_prob

给定词典=[我们 学习 人工 智能 人工智能 未来 是], 另外我们给定unigram概率:p(我们)=0.25, p(学习)=0.15, p(人工)=0.05, p(智能)=0.1, p(人工智能)=0.2, p(未来)=0.1, p(是)=0.15

实现逻辑

Step 1: 对于给定字符串:”我们学习人工智能,人工智能是未来“, 找出所有可能的分割方式

  • [我们,学习,人工智能,人工智能,是,未来]
  • [我们,学习,人工,智能,人工智能,是,未来]
  • [我们,学习,人工,智能,人工,智能,是,未来]
  • 我们,学习,人工智能,人工,智能,是,未来] …

Step 2: 我们也可以计算出每一个切分之后句子的概率

  • p(我们,学习,人工智能,人工智能,是,未来)= -log p(我们)-log p(学习)-log p(人工智能)-log p(人工智能)-log p(是)-log p(未来)
  • p(我们,学习,人工,智能,人工智能,是,未来)=-log p(我们)-log p(学习)-log p(人工)-log p(智能)-log p(人工智能)-log p(是)-log p(未来)
  • p(我们,学习,人工,智能,人工,智能,是,未来)=-log p(我们)-log p(学习)-log p(人工)-log p(智能)-log p(人工)-log p(智能)-log p(是)-log p(未来)等等
    Step 3: 返回第二步中概率最大的结果,也就是-log和最小的

关于为什么用log?
如果此项在语料库中出现次数比较少,有可能出现underflow的情况,解决办法就是加上log,log是严格递增的函数,原本的关系也是仍然成立的,在比较的情况下是等同的。

代码实现

import math
import xlrd

# TODO: 第一步: 从dic.txt/dic.xlsx中读取所有中文词。
print("Reading dic...")
# 获取对象
workbook = xlrd.open_workbook("中文词库.xlsx")

dic_words = []  # 保存词典库中读取的单词

# 获取第一个sheet的对象列表
booksheet = workbook.sheet_by_index(0)

rows = booksheet.get_rows()
for row in rows:
    dic_words.append(row[0].value)

print("len:" + str(len(dic_words)))
# 以下是每一个单词出现的概率。为了问题的简化,我们只列出了一小部分单词的概率。 在这里没有出现的的单词但是出现在词典里的,统一把概率设置成为0.00001
# 比如 p("学院")=p("概率")=...0.00001

word_prob = {"北京": 0.03, "的": 0.08, "天": 0.005, "气": 0.005, "天气": 0.06, "真": 0.04, "好": 0.05, "真好": 0.04, "啊": 0.01,
             "真好啊": 0.02,
             "今": 0.01, "今天": 0.07, "课程": 0.06, "内容": 0.06, "有": 0.05, "很": 0.03, "很有": 0.04, "意思": 0.06, "有意思": 0.005,
             "课": 0.01,
             "程": 0.005, "经常": 0.08, "意见": 0.08, "意": 0.01, "见": 0.005, "有意见": 0.02, "分歧": 0.04, "分": 0.02, "歧": 0.005}

print(sum(word_prob.values()))

# TODO:计算-log(x)
for word in word_prob.keys():
    word_prob[word] = round(-math.log(word_prob[word]), 1)

print(word_prob)

# TODO:利用递归计算所有可行的分词之后的结果
def word_break(s, dic):
    def sentences(cur):
        result = []
        if cur < len(s):
            for next in range(cur + 1, len(s) + 1):
                if s[cur:next] in dic: #列表切片是前闭后开的过程
                    result = result + [s[cur:next] + (tail and ',' + tail) for tail in sentences(next)]
        else:
            return ['']
        return result

    list_new = []
    for line in sentences(0):
        line = line.split(",")
        list_new.append(line)
    return list_new


def word_segment_naive(input_str):
    """
    1. 对于输入字符串做分词,并返回所有可行的分词之后的结果。
    2. 针对于每一个返回结果,计算句子的概率
    3. 返回概率最高的最作为最后结果

    input_str: 输入字符串   输入格式:“今天天气好”
    best_segment: 最好的分词结果  输出格式:["今天","天气",""]
    """

    # TODO: 第一步: 计算所有可能的分词结果,要保证每个分完的词存在于词典里,这个结果有可能会非常多。
    segments = word_break(input_str, dic_words)  # 存储所有分词的结果。如果次字符串不可能被完全切分,则返回空列表(list)
    # 格式为:segments = [["今天",“天气”,“好”],["今天",“天“,”气”,“好”],["今“,”天",“天气”,“好”],...]

    # TODO: 第二步:循环所有的分词结果,并计算出概率最高的分词结果,并返回
    best_segment = []
    best_score = math.inf # best_score初始值等于正无穷大
    for seg in segments:
        score = 0
        for w in seg:
            if w in word_prob.keys():
                score += word_prob[w]
            else:
                score += round(-math.log(0.00001), 1)
        if score < best_score:
            best_score = score
            best_segment = seg

    return best_segment


# TODO:测试
print(word_segment_naive("北京的天气真好啊"))
print(word_segment_naive("今天的课程内容很有意思"))
print(word_segment_naive("经常有意见分歧"))

参考博客

学人工智能的猜猜
Divine0

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Huggingface自然语言处理详解——基于BERT中文模型的任务实战》源码是一份用于展示如何使用Huggingface库进行自然语言处理任务的示例代码。该代码基于BERT中文模型,旨在帮助读者理解如何使用该模型进行文本分类、情感分析等任务。 该源码由以下几个部分组成: 1. 导入必要的库:代码开始部分导入了需要使用的Huggingface库,包括`transformers`和`tokenizers`。这些库提供了BERT模型以及相关的处理函数和工具。 2. 数据预处理:接下来,源码介绍了如何进行数据预处理。这包括读取数据集、分词、编码等步骤。具体来说,使用`BertTokenizer`类对文本进行分词,并使用`BertTokenizer.from_pretrained`加载预训练的BERT中文模型。 3. 构建模型:源码构建了一个简单的BERT分类模型,使用`BertForSequenceClassification`类来实现。这个模型有一个BERT编码器和一个用于分类的线性层。 4. 训练模型:通过`Trainer`类,源码进行了模型的训练。在训练过程中,使用了一个训练集和一个验证集,并定义了相应的训练参数,如学习率、批大小等。训练过程中,模型参数逐渐更新,直到达到设定的最大训练轮数。 5. 模型评估:训练完成后,源码进行模型评估。通过计算准确率、查全率、查准率等指标,评估模型在验证集上的性能。 总的来说,《Huggingface自然语言处理详解——基于BERT中文模型的任务实战》源码提供了一个完整的BERT模型应用示例,通过该源码,读者能够了解如何使用Huggingface库中的BERT模型进行中文文本分类任务,并学会了如何进行数据预处理、构建模型、训练和评估模型等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值