【Hanlp源码分析】基于感知机实现人名性别预测

本文深入分析HanLP中基于感知机的人名性别预测模块,探讨感知机算法原理及其实现细节,包括模型训练、评估过程及优化方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【Hanlp源码分析】基于感知机实现人名性别预测

本文是分析github中著名的开源NLP工业级代码——hanlp的实现细节,其作者是何晗。

0.总结

Get to the points first. The article comes from LawsonAbs!
  • part1:感知机算法简介
  • part2:【Hanlp源码分析】基于感知机实现人名性别预测

1.什么是感知机算法?

  • 属于监督学习算法
    比如在后面给出的实战代码中,我们给出了人名对应的性别,会根据这个预测是否准确去完成一次更新操作。

  • 属于迭代式算法
    每次读入一个样本,执行预测,将预测结果与正确答案进行对比,计算误差,根据误差更新模型参数。

2.有什么用途?

  • 可以用于问题分类

3.有什么利弊?

  • 模型过于简单
    参数较少的模型就容易出现 “不拟合” 的情况,同时,也会因为数个偏离点而对迭代更新的参数有很大的影响。从而难以准确的预测结果,造成较大偏差。

  • 迭代偏差
    这里说的迭代偏差是因为我们总是倾向于取最后一次迭代的模型。
    每次迭代都产生一个模型,而且每个模型的对应的每个参数不一定相同。如果我们单纯的取最后一次迭代产生的模型作为“最优模型”的话,很有可能是 “补了西墙,拆了东墙”

3.怎么改进?

针对上面叙述的问题,对应的改进方法有投票感知机和平均感知机,分别简单叙述一下。

3.1 投票感知机

3.1.1 思想

每次迭代都会产生一个不同参数的模型,那么这些模型间的准确率就不一样,把这个准确率称之为权重。根据各个模型的权重可以得到每个模型的加权平均值。根据各个模型的加权平均值与参数相乘,得到最终的一个模型。

3.1.2 缺点
  • 计算开销大
  • 存储开销大

3.2 平均感知机

3.2.1 思想

每次迭代都会产生一个不同参数的模型,最后得到的模型就取每次迭代模型的一个平均。【这个平均其实指的是模型参数的平均】【《自然语言处理入门》这本书中讲的是:取多个模型权重的平均。我不是很理解。】

3.2.2 特点
  • 好实现
  • 借助一定的方法【累积参数和,而不是傻傻的每迭代一次就算一次平均】,可以避免存储中间模型,可以以更少内存得到最终的模型

下面开始讲第二部分,分析感知机算法中最简单的【朴素感知机】的代码实现。因为原作者用的是Java,所以会涉及到一些Java的语法知识。后期我会造出 python 版的轮子。


4.主要类

4.1 NameGenderClassification

在这里插入图片描述main() 是入口函数, trainAndEvaluate()中会训练模型【classifier.train(…)】,会将得到的模型进行效果评估【classifier.evaluate(…)】。

4.2 PerceptronClassifier

这个抽象类中实现了 上述的 train方法。如下所示:
在这里插入图片描述
这里主要做了几件事儿:

  • 初始化一个特征字典(featureMap),这个就是将人名中除去姓氏的名字做一个映射。
  • 读取语料库【 reandInstance(corpus,featureMap)
    这是很重要的一部分内容,其关键问题是:如何把语料库信息转换为数据信息? 下面慢慢谈。
    (1)corpus是语料库的地址,为了便于测试,这里我用了一个自己编辑的语料库做训练集。内容如下:
    在这里插入图片描述
    这里传入 featureMap 的原因就是因为在读取语料库时 将特征写入Map中。在看如何将语料信息转换为数据信息之前,有必要了解一下 类 Instance 中的定义,这里的 Instance就代表是语料库中的一行数据。
    在这里插入图片描述
    这里的 Instance 包含两个属性:
    (1)特征向量
    (2)标签【即应该得到的正确分类结果】
    这里的特征向量存在方式很特别。通常的文字转向量采用的编码方式有one-hot编码,但是这里采用的是记录下标的方式。这样做是为了减少内存开销,加速计算。
    下面我以上面的语料库举个例子:由 “范仲淹,男”这行数据,可以得到一个两个特征=> 仲和淹。因为它们都是第一次出现,所以就直接放到 featureMap 中,得到的就是0和1,因为范仲淹是男性,所以最终得到的 Instance 实例就是 x=[0,1], y=-1。其中 x是一个LinkedList 型的对象。
    在这里插入图片描述

extractFeature方法featureList中的值如下所示:仲对应0,淹对应1…后面同样的道理。
在这里插入图片描述其中会调用的几个方法如下:
addFeature方法
在这里插入图片描述
注意到 readInstance 方法返回的是一个 Instance 的数组。如果用Instance[] instArray = new Instance[200]; //直接使用 Instance[] 去直接生成一个数组将显得有写生硬且浪费。

  • 根据参数 averagePerceptron 选择是进行何种训练方式?我这里就分析朴素感知机,其他的都很相似,除了平均感知机做了一个简单的内存和计算优化,也没啥的。
    这里是最主要的内容。下面我们慢慢谈。

在这里插入图片描述这里的感知机机制就是: y=w*x + b。提炼一下就得到y = wx,因为代码中存储的特征是下标值【其实际含义是:该值下标对应的值为1】,所以直接采用y+=parameter[f]的这种形式就可以得到一个模拟结果。数组parameter[] 的初始值赋为0。代码如下:
在这里插入图片描述如果预测结果部队,则需要对该预测过程涉及到的参数进行更新:
在这里插入图片描述
这里的更新过程也是结合了相关的推导进行了简化。因为只有预测错了才会对参数进行更新。分类讨论一下:
当预测结果为-1,而正确结果为1时,因为特征向量x的值不可变,且其恒为正,所以我们可以将w的值变大,从而得到一个更大结果值,所以可以直接进行parameter[f]+=y操作;
相应的,当预测结果为1时,可得到相反的结论。

  • 最后评价这个模型的效果【evaluate(instanceList)
    跑出的结果如下所示:
    在这里插入图片描述

因为训练集合就一点儿数据,所得到的准确率很低,当将训练集换成正常的语料库之后,可以得到一个很好的预测效果:
在这里插入图片描述

HanLP是一系列模型算法组成的NLP工具包,由大快搜索主导并完全开源,目标是普及自然语言处理在生产环境中的应用.HanLP具备功能完善,性能高效,架构清晰,语料时新,可自定义的特点。 HanLP提供下列功能: 中文分词 HMM-两字组(速度与精度最佳平衡;一百兆内存) 最短路分词,N-最短路分词 由字构词(侧重精度,全世界最大语料库,可识别新词;适合NLP任务) 感知机分词,CRF分词 词典分词(侧重速度,每秒数千万字符;省内存) 极速词典分词 所有分词器都支持: 索引全切分模式 用户自定义词典 兼容繁体中文 训练用户自己的领域模型 词性标注 HMM词性标注(速度快) 感知机词性标注,CRF词性标注(精度高) 命名实体识别 基于HMM角色标注的命名实体识别(速度快) 中国人名识别,音译人名识别,日本人名识别,地名识别,实体机构名识别 基于线性模型的命名实体识别(精度高) 感知机命名实体识别,CRF命名实体识别 关键词提取 TextRank关键词提取 自动摘要 TextRank自动摘要 短语提取 基于互信息和左右信息熵的短语提取 拼音转换 多音字,声母,韵母,声调 简繁转换 简繁分歧词(简体,繁体,台湾正体,香港繁体) 文本推荐 语义推荐,拼音推荐,字词推荐 依存句法分析 基于神经网络的高性能依存句法分析器 基于ArcEager转移系统的柱搜索依存句法分析器 文本分类 情感分析 文本聚类 KMeans,Repeated Bisection,自动推断聚类数目k word2vec 词向量训练,加载,词语相似度计算,语义运算,查询,KMEANS聚类 文档语义相似度计算 语料库工具 部分默认模型训练自小型语料库,鼓励用户自行训练。模块所有提供训练接口,语料可参考98年人民日报语料库。 在提供丰富功能的同时,HanLP内部模块坚持低耦合,模型坚持惰性加载,服务坚持静态提供,词典坚持明文发布,使用非常方便。默认模型训练自全世界最大规模的中文语料库,同时自带一些语料处理工具,帮助用户训练自己的模型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

说文科技

看书人不妨赏个酒钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值