机器学习——CBOW基于矩阵(手动实操)

基于矩阵的CBOW基础算法,其实是负采样的前提算法。

主要是根据
在这里插入图片描述

预测准确率为22%左右
在这里插入图片描述
说实话。。。我已经很满意了,至少这个东西是可以去预测的,至于预测为什么不正确,我目前猜测主要还是跟词频有关。

在结果中,and和the、a的预测准确率较高,经过打印词频,确实词频高
在这里插入图片描述
但其中,预测准确的,也有一些低词频的词汇,所以这个方式目前是可用的。
至于预测效果是否好,主要还是看调参了,比如迭代次数、比如学习率等等。
但这不是我重点考虑的。
我只要模型流程是正确的,能跑的通。

import math
import numpy as np
from docx import Document
import re
import pandas as pd
import random
random.seed(0)
pd.options.display.max_rows = None
"""
需要提前设置的参数:doc_path语料的word文档、η学习率、词向量的维度W_columns、iterate_times迭代次数、context_word_num单个上下文的词数量
+++++++ 【W词向量的所有初始值、θ霍夫曼树非叶子节点上的权重参数】:这两个关键参数在后续用正态分布随机树来进行初始化 ++++
"""
doc_path = r"simple_word.docx"
η = 0.01
W_columns = 10
iterate_times = 50
context_word_num = 4# 获取语料库C+统计无重复单词的词典D
doc = Document(doc_path)
C_list = []
all_text = ''
for i in doc.paragraphs:if len(i.text) != 0:para = [x for x in re.split(' |!|\?|\.|。|,|,|\(|\)', i.text) if x]C_list.append(para)all_text = all_text + i.text
words_org = [x for x in re.split(' |!|\?|\.|。|,|,|\(|\)', all_text) if x]
# 统计每个单词的词频,word_count是series数据类型
word_count = pd.value_counts(words_org)
print(word_count)
raise Exception
"""词典D转独热编码"""
D_list = set(words_org)
N = len(D_list)
D_onehot = {}
for index, value in enumerate(D_list):temp = [0] * Ntemp[index] = 1D_onehot[value] = tempdel temp
# 最终词典D的独热编码为D_df
D_df = pd.DataFrame(D_onehot)"""初始化词向量矩阵W:W_columns个维度特征"""
# 这意味着后续的中间向量h和关键词参数向量u,都是用3个值表示,如 h=[1,10,20]
W_dict = {}
for index, word in enumerate(D_list):W_dict[word] = [random.random() for i in range(W_columns)]
# 最终词向量用W_df表示
W_df = pd.DataFrame(W_dict)
print(f"初始的词向量W为")
print(W_df)"""初始化关键词的参数向量u:u的维度特征个数,跟w、h保持一致"""
u_dict = {}
for index, word in enumerate(D_list):u_dict[word] = [1 for i in range(W_columns)]
# 最终关键词参数向量用u_df表示
u_df = pd.DataFrame(u_dict)
print(f"初始的关键词参数向量u为")
print(u_df)# 每一个u的迭代,都需要所有上下文中间向量h的累加,每一个w的迭代,都需要所有u的累加
# 先迭代u,u迭代完变为一个新的u_new后,再用所有的u_new去依次迭代所有的w。"""第3阶段反向传播:把所有上下文存进列表里"""
# 由于我们要迭代很多次,所以每次都重新选取上下文,会非常耗时
# 因此,不如一次性,把所有的上下文都选取后,放进一个列表里边
# 这样,以后无论迭代多少次,上下文都是一样的,不需要重复选取
c = context_word_num//2
y_and_context_list = []
y_h_dict = {}
for sentence in C_list:for index, word in enumerate(sentence):"""获取单个上下文"""y = wordcontext = []if index-2>=0:context.append(sentence[index-1])if index-2>=0:context.append(sentence[index-2])if index+1<len(sentence):context.append(sentence[index+1])if index+2<len(sentence):context.append(sentence[index+2])"""计算单个上下文的中间向量h"""h = list(W_df[context].sum(axis=1))y_and_context = (y, h,context)y_h_dict[y]=list(h)y_and_context_list.append(y_and_context)
"""y和h有个对应的dataframe表:每个关键词都有一个对应的中间向量h"""
y_h_df = pd.DataFrame(y_h_dict)def sigmoid(x, y):sig = np.matmul(x, y)try:result = 1 / (1.0 + math.exp(-sig))except OverflowError:result = 1 / (1.0 + math.exp(700))return result"""反向传播:根据每个上下文和对应的待预测单词y,去迭代u和w"""
for i in range(iterate_times):print(f"第{i + 1}次迭代")h_temp = 0.0"""所有关键词的参数向量u的迭代"""for y_and_context in y_and_context_list:y, h,context = y_and_contextu_old = u_df[y]u_temp = 0.0for y_index in y_h_df:if y_index == y:l_word = 1else:l_word = 0h_row = y_h_df[y_index]"""u的迭代公式涉及所有h的累加计算"""u_temp += η*(l_word-sigmoid(u_old,h_row))*h_rowu_new = u_old + u_tempu_df[y] = u_new"""所有词向量w的迭代"""for y_and_context in y_and_context_list:y, h,context = y_and_contextw_temp = 0.0for y_index in u_df:if y_index == y:l_word = 1else:l_word = 0u_row = u_df[y_index]"""w的迭代公式涉及所有u的累加计算"""w_temp += η*(l_word-sigmoid(u_row,h))*u_rowfor word in context:W_df[word] = W_df[word] + w_temp
print(f"迭代后的词向量W为")
print(W_df)"""迭代后预测,预测的方式:每个h与所有的u分别进行乘积后,再softmax,看哪个值比较大,就预测为哪个关键词"""
def get_mom(a,b_df): # 计算softmax的分母部分mom = 0for b in b_df:temp = np.matmul(a,b_df[b])mom += math.exp(temp)return momdef softmax(a,b,b_df): # 计算最终的softmax值mom = get_mom(a,b_df)son = math.exp(np.matmul(a,b))result = son/momreturn result
"""预测关键词:h和所有的u分别计算出softmax值,其中softmax值最大的为对应的预测关键词"""
def predict(a,b_df): # 预测关键词y_predict = {'max_softmax':0,'y_index':None}for y_index in b_df:softmax_now = softmax(a, b_df[y_index], b_df)if softmax_now>y_predict['max_softmax']:y_predict['max_softmax'] = softmax_nowy_predict['y_index'] = y_indexif y_predict['y_index'] == None:print("无法预测,报错")else:return y_predict['y_index']pre_result = []
for y_and_context in y_and_context_list:y, h, context = y_and_contexth = list(W_df[context].sum(axis=1))y_pre = predict(h,u_df)if y_pre == y:print(f"{y}预测准确,上下文为:{context}")pre_result.append(1)else:print(f"{y}预测错误,预测值为{y_pre},,上下文为:{context}")pre_result.append(0)
print(f"预测准确率为:{sum(pre_result)/len(pre_result)*100}%")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/491481.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

onlyoffice api开发

编写代码 按照https://api.onlyoffice.com/editors/basic编写代码 <html> <head><meta charset"UTF-8"><meta name"viewport"content"widthdevice-width, user-scalableno, initial-scale1.0, maximum-scale1.0, minimum-scal…

【数据结构初阶 7】二叉树:链式二叉树的基本操作实现

文章目录 &#x1f308; Ⅰ 定义二叉树结点&#x1f308; Ⅱ 创建二叉树结点&#x1f308; Ⅲ 遍历二叉树1. 先序遍历2. 中序遍历3. 后序遍历4. 层序遍历 &#x1f308; Ⅳ 销毁二叉树 &#x1f308; Ⅰ 定义二叉树结点 1. 每个结点都由三部分组成 数据域&#xff1a;存储本结…

matlab绘制雷达图和二维FFT变换图

1、内容简介 略 49-可以交流、咨询、答疑 matlab绘制雷达图和二维FFT变换图 NMO组及NORMAL组 RNFL层、GCL层、IPL层、GCC层、ORL层做雷达图&#xff08;共10张&#xff09; 2、内容说明 略 NMO组及NORMAL组 RNFL层、GCL层、IPL层、GCC层、ORL层请分别做雷达图&#xff08…

linux之前后端项目部署与发布

目录 前言 简介 一、安装Nginx 二、后端部署 2.1多个tomcat负载均衡 2.2 负载均衡 2.3 后端项目部署 三、前端部署 1.解压前端 2.Nginx配置文件修改 3.IP域名映射 4.重启Nginx服务 前言 上篇博主已经讲解过了单机项目的部署linux之JAVA环境配置JDK&Tomcat&a…

Linux基础命令—系统服务

基础知识 centos系统的开机流程 1)通电 2)BIOS硬件检查 3)MBR引导记录 mbr的引导程序 加载引导程序 让硬件加载操作系统内核 MBR在第一个磁盘第一个扇区 总大小512字节 mbr: 1.引导程序: 占用446字节用于引导硬件,加载引导程序 2.分区表: 总共占…

文献阅读:Large Language Models are Null-Shot Learners

文献阅读&#xff1a;Large Language Models are Null-Shot Learners 1. 文章简介2. 方法介绍3. 实验考察 & 结论 1. 基础实验 1. 实验设计2. 实验结果 2. 消融实验 1. 小模型上的有效性2. ∅CoT Prompting3. 位置影响4. 组成内容 4. 总结 & 思考 文献链接&#xff1…

Zookeeper客户端命令、JAVA API、监听原理、写数据原理以及案例

1. Zookeeper节点信息 指定服务端&#xff0c;启动客户端命令&#xff1a; bin/zkCli.sh -server 服务端主机名:端口号 1&#xff09;ls / 查看根节点下面的子节点 ls -s / 查看根节点下面的子节点以及根节点详细信息 其中&#xff0c;cZxid是创建节点的事务id&#xff0c…

Python 鼠标模拟

鼠标模拟即&#xff1a;通过python 进行模拟鼠标操作 引入类库 示例如下&#xff1a; import win32api import win32con import time 设置鼠标位置 设置鼠标位置为窗口中的回收站。 示例如下&#xff1a; # 设置鼠标的位置 win32api.SetCursorPos([30, 40]) 双击图标 设置…

vue:find查找函数实际开发的使用

find的作用&#xff1a; find 方法主要是查找数组中的属性&#xff0c;会遍历数组&#xff0c;对每一个元素执行提供的函数&#xff0c;直到找到使该函数返回 true 的元素。然后返回该元素的值。如果没有元素满足测试函数&#xff0c;则返回 undefined。 基础使用&#xff1a…

五、数组——Java基础篇

六、数组 1、数组元素的遍历 1.1数组的遍历&#xff1a;将数组内的元素展现出来 1、普通for遍历&#xff1a;根据下表获取数组内的元素 2、增强for遍历&#xff1a; for&#xff08;数据元素类型 变量名&#xff1a;数组名&#xff09;{ 变量名&#xff1a;数组内的每一个值…

python统计分析——多解释变量的方差分析

参考资料&#xff1a;用python动手学统计学 1、导入库 # 导入库 # 用于数值计算的库 import numpy as np import pandas as pd import scipy as sp from scipy import stats # 用于绘图的库 from matplotlib import pyplot as plt import seaborn as sns sns.set() # 用于估计…

docker-compose 搭建laravel环境

laravel环境包含nginx,mysql,php7.4,redis 一、安装好docker后pull镜像 1.nginx镜像 docker pull nginx:latest单独启动容器 docker run --name nginx -p 80:80 -d nginx 2.php镜像 docker pull php:7.4-fpm3.mysql镜像 docker pull mysql:5.74.redis镜像 docker pull r…