欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 词向量引入词性【原创代码】

程序员文章站 2022-05-31 11:01:50
文章目录摘要预设词性特征完整代码示例效果比较摘要对训练后的词向量,引入预设词性特征应用场景:关键词抽取提升、命名实体识别提升…大家可以根据自身业务场景来选择是否引入词性预设词性特征使用独热码,数值设计上是,希望提升词性相同或相近的词,打个比方:【果】和【瓜】都是名词,提升相似度;【吃】和【且】分别是动词和连词,不提升相似度;【文案】是名词,【策划】是动名词,相似度提升一丢丢。【唱歌】和【艺术】都是实词,也给予一丢丢丢的相似度提升补充:这个词性特征是根据语言学预设的,我们也可...

摘要

  • 对训练的词向量,引入预设词性特征
  • 应用场景:关键词抽取提升、命名实体识别提升…
  • 大家可以根据自身业务场景来选择是否引入词性

预设词性特征

使用独热码,数值设计上是,希望提升词性相同或相近的词,打个比方:
【果】和【瓜】都是名词,提升相似度;
【吃】和【且】分别是动词和连词,不提升相似度;
【文案】是名词,【策划】是动名词,相似度提升一丢丢。
【唱歌】和【艺术】都是实词,也给予一丢丢丢的相似度提升

荐
                                                        词向量引入词性【原创代码】

补充:这个词性特征是根据语言学预设的,我们也可以尝试用词向量来训练词性特征。

完整代码示例

from jieba.posseg import dt
import numpy as np, jieba
from gensim.models import Word2Vec

FLAG2VECTOR = {
    'a': [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'ad': [0.6, 0, 0.4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'ag': [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'an': [0.6, 0, 0, 0, 0, 0, 0, 0.4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'b': [0.5, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'c': [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'd': [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'e': [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'f': [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'g': [0.2, 0, 0.1, 0, 0, 0.2, 0, 0.3, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0],
    'i': [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'j': [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'l': [0, 0, 0, 0, 0, 0.6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.4],
    'm': [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'mq': [0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0],
    'n': [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'ng': [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'nr': [0, 0, 0, 0, 0, 0, 0, 0.1, 0.9, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'nrfg': [0, 0, 0, 0, 0, 0, 0, 0.1, 0.8, 0.1, 0, 0, 0, 0, 0, 0, 0, 0],
    'nrt': [0, 0, 0, 0, 0, 0, 0, 0.1, 0.8, 0.1, 0, 0, 0, 0, 0, 0, 0, 0],
    'ns': [0, 0, 0, 0, 0, 0, 0, 0.1, 0.1, 0.8, 0, 0, 0, 0, 0, 0, 0, 0],
    'nt': [0, 0, 0, 0, 0, 0, 0, 0.8, 0.1, 0.1, 0, 0, 0, 0, 0, 0, 0, 0],
    'nz': [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'o': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
    'p': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
    'q': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
    'r': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
    's': [0, 0, 0, 0, 0.6, 0, 0, 0, 0, 0.4, 0, 0, 0, 0, 0, 0, 0, 0],
    't': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
    'u': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
    'v': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
    'vg': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
    'vn': [0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0],
    'x': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],  # 全0
    'y': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
    'z': [0.7, 0, 0.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    'zg': [0.4, 0, 0.1, 0, 0, 0.1, 0, 0.3, 0, 0, 0, 0, 0, 0, 0, 0, 0.1, 0],
}
word2flag = lambda w: dt.word_tag_tab.get(w)  # 根据词获取词性
word2flag2vec = lambda w: FLAG2VECTOR.get(word2flag(w), FLAG2VECTOR['x'])  # 根据词获取词性,然后根据词性获取向量
dimension = FLAG2VECTOR['x'].__len__()  # 词性特征维度

"""词向量"""
SIZE = 100  # 词向量维度
WINDOW = 11


class Word2Vector:
    def __init__(self, texts):
        sentences = [jieba.lcut(text) for text in texts]  # 文本切分
        wv = Word2Vec(sentences, size=SIZE, window=WINDOW, min_count=1).wv  # 词向量训练
        self.index2word = wv.index2word
        fv = np.array([word2flag2vec(w) for w in wv.index2word])  # 词性矩阵
        self.vectors = wv.vectors  # 训练好的词矩阵
        self.vectors = np.concatenate((fv, self.vectors), axis=1)  # 词矩阵与词性矩阵拼接
        self.vectors = np.concatenate((np.zeros((1, SIZE + dimension)), self.vectors), axis=0)  # 拼接一个空向量:未登录词
        self.w2i = {w: i for i, w in enumerate(wv.index2word, 1)}  # 词 -> 词ID

    def w2v(self, w):
        """词 -> 向量"""
        return self.vectors[self.w2i.get(w, 0)]

    def cosine(self, w1, w2):
        """余弦相似度"""
        vec1, vec2 = self.w2v(w1), self.w2v(w2)
        return vec1 @ vec2 / (np.linalg.norm(vec1) * np.linalg.norm(vec2))

    def similar_by_word(self, word):
        """输入一个词,返回相似词"""
        return sorted(((self.cosine(w, word), w) for w in self.index2word), reverse=True)
if __name__ == '__main__':
    _m = Word2Vector('''
    《英雄联盟》灵魂莲华通行证怎么样 通行证奖励一览
    lol莉莉娅隐藏任务怎么做 英雄联盟莉莉娅隐藏完成攻略
    lol幸运召唤师7月最新入口 英雄联盟7月幸运召唤师官网活动地址
    LOL英雄联盟10.5新版本维护公告最新 3月10日lol维护到几点
    英雄联盟lpl夏季赛2020赛程表 2020lpl夏季赛7月24日对战名单
    LOL4月4日停机补偿 4月4日游戏补偿领取内容汇总
    lol3月阿卡丽的神秘商店2020地址 阿卡丽的黑金商店2020官网
    单身狗的情人“劫”怎样才能不孤单?
    又双叒叕是情人节,女朋友礼物该怎么送?
    信仰不仅用来膜拜!ROG两款定制电竞本为玩家提供定制体验
    LGD群访 Kramer:就我们队全部都是“关键先生”
    季后赛形势变化 RNG已基本挥别季后赛
    永恩英雄剖析:与恶魔合为一体的刺客英雄
    RNG vs LGD 第3场 2020LPL夏季赛
    RNG vs LGD 比赛视频 2020LPL夏季赛
    【战报】RNG痛失好局 寒冰多次关键开团助LGD赢下比赛
    英雄联盟:云顶之弈公开赛-TOC线上赛区复赛来袭,赛制全方位解析!
    LPL每日综述:TES2:0轻松击杀DMO JDG以2:1赢下LNG
    '''.strip().split())
    while True:
        try:
            for _similarity, _word in _m.similar_by_word(input('相似词模型:').strip())[:10]:
                print(word2flag(_word), _word, _similarity)
        except KeyError:
            pass

效果比较

拿了1.7万长文本(新闻)来训练,效果如下

荐
                                                        词向量引入词性【原创代码】

如第一个图示:
引入词性前,漂亮可以找出被修饰的名词,如小姑娘脸蛋酒窝
而引入词性后,找到的多是形容词。

荐
                                                        词向量引入词性【原创代码】

如第二个图示:
天然无添加的词向量制备可以找出相关的名词,如晶体等;
而引入词性后,找到的多是动词。

本文地址:https://blog.csdn.net/Yellow_python/article/details/107548264

相关标签: 自然语言处理