one-hot Embedding 理论知识详解 + 代码实操 (为学习笔记模式,同时附完整代码)【独热向量编码】

2023-11-15

目   标使用one-hot Embedding 处理数据库查询语句,使其变成向量模式,以下为个人学习笔记和学习过程中用到的完整代码。

环   境:腾讯云服务器 Linux系统(具体环境会在代码段前进行标注)

目录

一、one-hot 理论基础

二、用 one-hot 处理句子?

三、用one-hot处理查询语句

四、如果我使用更长的查询语句呢?one-hot能处理吗?

4.1 字符型数据的单引号屏蔽问题

4.2 如何依次读取文件夹中的sql文件并进行编码

五、解决“如何依次读取文件夹中的sql文件并进行编码”问题

5.1 如何用Python读取sql文件

5.2 如何用Python遍历文件夹中的文件

5.3 用Python遍历文件夹中的sql文件并将它们变成向量形式

Bing! 任务完成!

六、one-hot的优缺点总结

6.1 优点

6.2 缺点


一、one-hot 理论基础

进行机器学习,就需要对数据的特征进行提取,但有些数据是离散非连续的,这个时候就需要将这些特征转换为向量形式。

one-hot向量编码,就是将每个特征都进行0 1 表示,具体的解说可以参看下面这篇文章,它描述得非常详细。

【one-hot理论详解】https://blog.csdn.net/qq_38651469/article/details/121100275

下面放入一段使用了one-hot 的简单代码(python版本3.7.0)

from sklearn import preprocessing

enc = preprocessing.OneHotEncoder()
enc.fit([[0,0,3],[1,1,0],[0,2,1],[1,0,2]])

array = enc.transform([[1,2,3]]).toarray()

print(array)

【运行结果】

【解析】(都是自学的不一定对哈)

preprocessing.OneHotEncoder() 调用起One-hot

enc.fit([ ]) 传入了学习数据

enc.transform([1,2,3]) 得出了预测结果


二、用 one-hot 处理句子?

根据上面的实验,我做了进一步的测试,发现这种方法只能对数字特征进行编码,无法编译中英文,但我的目标是通过One-Hot编译查询语句,因此我的进阶学习路线为:用one-hot处理句子。

于是我找到了这篇文章:

【实现对文本的简单one-hot编码】https://blog.csdn.net/Einstellung/article/details/82865224?spm=1001.2014.3001.5506按照文章中所提到的,首先,使用one-hot对单词进行编码

from keras.preprocessing.text import Tokenizer

samples = ['The cat sat on the mat.', 'The dog ate my homework.']

tokenizer = Tokenizer(num_words=1000)  # i创建一个分词器(tokenizer),设置为只考虑前1000个最常见的单词

tokenizer.fit_on_texts(samples)   # 构建索引单词

sequences = tokenizer.texts_to_sequences(samples)   # 将字符串转换为整数索引组成的列表

one_hot_results = tokenizer.texts_to_matrix(samples, mode='binary')
#可以直接得到one-hot二进制表示。这个分词器也支持除了one-hot编码外其他向量化模式
print(one_hot_results)# 这个one-hot-result就是向量表示

word_index = tokenizer.word_index  # 得到单词索引
print('Found %s unique tokens.' % len(word_index))

【运行结果】(需要使用Keras框架)

【解析】

Keras框架自带One-hot编码方式,因此只给出要训练的语句就行了。

输出的三个东西分别是

①前面两个 0 1 向量序列是对

['The cat sat on the mat.', 'The dog ate my homework.']

的编码。

② “Found 9 unique tokens” 是指遇到了9个单词—— The出现两次所以选1个单词。


三、用one-hot处理查询语句

假设我有一个SQL查询语句如下:

SELECT MIN(mc.note) AS production_note,
       MIN(t.title) AS movie_title,
FROM company_type AS ct,
     info_type AS it,
     movie_companies AS mc,
WHERE ct.kind = 'production companies'
  AND it.info = 'top 250 rank'

那么我首先尝试将其放进Sample,代入Keras框架进行 one-hot向量表示

from keras.preprocessing.text import Tokenizer

samples = ['SELECT MIN(mc.note) AS production_note FROM company_type AS ct', 'SELECT MIN(t.title) AS movie_title']

tokenizer = Tokenizer(num_words=1000)  # i创建一个分词器(tokenizer),设置为只考虑前1000个最常见的单词

tokenizer.fit_on_texts(samples)   # 构建索引单词

sequences = tokenizer.texts_to_sequences(samples)   # 将字符串转换为整数索引组成的列表

one_hot_results = tokenizer.texts_to_matrix(samples, mode='binary')
#可以直接得到one-hot二进制表示。这个分词器也支持除了one-hot编码外其他向量化模式
print(one_hot_results)# 这个one-hot-result就是向量表示

word_index = tokenizer.word_index  # 得到单词索引
print('Found %s unique tokens.' % len(word_index))

可以看到的是——在这里,我将样本替换为了查询语句,实验结果证明,one-hot可以对其进行编码,并有效地查出了13个 “unique tokens”

【运行结果】

另,one-hot 似乎并不对标点符号进行编码


四、如果我使用更长的查询语句呢?one-hot能处理吗?

因为查询语句经常非常长,而且包含各种数据类型,不知道One-Hot能不能对这种混合数据模式进行编码,因此,下一步实验是——将sample里的查询语句加长

大家可以在代码中看到,我已经将查询语句的长度加长到了一个变态的程度

from keras.preprocessing.text import Tokenizer

samples = ['SELECT MIN(mc.note) AS production_note, MIN(t.title) AS movie_title, FROM company_type AS ct, info_type AS it, WHERE ct.kind = production companies AND it.info = top 250 rank AND mc.note NOT LIKE %(as Metro-Goldwyn-Mayer Pictures)%']

tokenizer = Tokenizer(num_words=1000)  # i创建一个分词器(tokenizer),设置为只考虑前1000个最常见的单词

tokenizer.fit_on_texts(samples)   # 构建索引单词

sequences = tokenizer.texts_to_sequences(samples)   # 将字符串转换为整数索引组成的列表

one_hot_results = tokenizer.texts_to_matrix(samples, mode='binary')
#可以直接得到one-hot二进制表示。这个分词器也支持除了one-hot编码外其他向量化模式
print(one_hot_results)# 这个one-hot-result就是向量表示

word_index = tokenizer.word_index  # 得到单词索引
print('Found %s unique tokens.' % len(word_index))

【运行结果】

————!!! WARNING !   !   ! 下图高度密集!密恐患者速速撤离!————

 就,跑也能跑,但向量也是真 的 大 啊

此外,在运行的过程中遇到了两个问题,都是必须考虑的。

4.1 字符型数据的单引号屏蔽问题

在查询语句中经常会带有字符型的数据,这些数据的单引号会造成错误,导致部分数据无法录入。

因此,在对带有字符型数据的查询语句进行编码时,就必须先对这些双引号进行屏蔽。

4.2 如何依次读取文件夹中的sql文件并进行编码

在训练的过程中,势必不可能总是手动将查询语句替换进去,因此还涉及到一个如何用Python进行文件夹读取并代入的问题


五、解决“如何依次读取文件夹中的sql文件并进行编码”问题

5.1 如何用Python读取sql文件

首先,拆解问题为:“如何用python读取sql文件”(先只读取一个文件,之后再尝试依次读取文件夹)

参考了下面这篇文章的做法:

【使用Python读取sql文件】https://blog.csdn.net/zyq_victory/article/details/90297701?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165595433116781818734050%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165595433116781818734050&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~pc_rank_34-5-90297701-null-null.142%5Ev20%5Epc_rank_34,157%5Ev15%5Enew_3&utm_term=%E5%A6%82%E4%BD%95%E7%94%A8python%E8%AF%BB%E5%8F%96sql%E6%96%87%E4%BB%B6&spm=1018.2226.3001.4187

根据服务器的路径,将代码改造如下:

# sql文件夹路径
sql_path = '/root/Liujq/a_onehot/onehot_data' + '/'

# sql文件名, .sql后缀的
sql_file = '1a.sql'

# 读取 sql 文件文本内容
sql = open(sql_path + sql_file, 'r', encoding='utf8')
sqltxt = sql.readlines()
# 此时 sqltxt 为 list 类型

# 读取之后关闭文件
sql.close()

# list 转 str
sql = "".join(sqltxt)

# 输出一下看看能不能完整地读出来
print(sql)

可以,能读得出来:


5.2 如何用Python遍历文件夹中的文件

然后,尝试将文件夹里的所有sql文件依次读出 (下面这个代码只能读取出文件名,就是看看能不能读)

import os

path = '/root/Liujq/a_onehot/onehot_data'
for filename in os.listdir(path): #读取Path路径下的文件名
    print(filename)


5.3 用Python遍历文件夹中的sql文件并将它们变成向量形式

import os
from keras.preprocessing.text import Tokenizer

path = '/root/Liujq/a_onehot/onehot_data/'
for filename in os.listdir(path): #读取Path路径下的文件,此时文件名是指针形式。
    print(filename)
    # 读取 sql 文件文本内容
    sql = open(path + filename, 'r', encoding='utf8')
    sqltxt = sql.readlines()
    # 此时 sqltxt 为 list 类型

    # 读取之后关闭文件
    sql.close()

    # list 转 str
    sql = "".join(sqltxt) #得到str形式的sql文件内容

    # 将sql内容放进要被转换的samples里
    samples = [sql]
    tokenizer = Tokenizer(num_words=1000)  # i创建一个分词器(tokenizer),设置为只考虑前1000个最常见的单词

    tokenizer.fit_on_texts(samples)  # 构建索引单词

    sequences = tokenizer.texts_to_sequences(samples)  # 将字符串转换为整数索引组成的列表

    one_hot_results = tokenizer.texts_to_matrix(samples, mode='binary')
    # 可以直接得到one-hot二进制表示。这个分词器也支持除了one-hot编码外其他向量化模式
    print(one_hot_results)  # 这个one-hot-result就是向量表示

    word_index = tokenizer.word_index  # 得到单词索引
    print('Found %s unique tokens.' % len(word_index))

    print('==============================================================')


Bing! 任务完成!

代码确实能用,就是输出效果过于密恐,不给大家展示了hhh


六、one-hot的优缺点总结

总结来自这篇文章:

one-hot编码优缺点分析https://blog.csdn.net/qq_38651469/article/details/121100275?spm=1001.2014.3001.5506

6.1 优点

(1) 解决了分类器不好处理离散数据 的问题。

    a. 欧式空间。在回归,分类,聚类等机器学习算法中,特征之间距离计算 或 相似度计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。

    b. one-hot 编码。使用 one-hot 编码,将离散特征的取值扩展到了欧式空间,离散特征的某个取值 就 对应欧式空间的某个点。将离散型特征使用 one-hot 编码,确实会让 特征之间的距离计算 更加合理。

(2) 在一定程度上也起到了 扩充特征的作用。

6.2 缺点

在文本特征表示上有些缺点就非常突出了。

(1) 它是一个词袋模型,不考虑 词与词之间的顺序(文本中词的顺序信息也是很重要的);

(2) 它 假设词与词相互独立(在大多数情况下,词与词是相互影响的);

(3) 它得到的 特征是离散稀疏 的 (这个问题最严重)。

上述第3点展开:
(1) 为什么得到的特征是离散稀疏的?

    例如,如果将世界所有城市名称作为语料库的话,那这个向量会过于稀疏,并且会造成维度灾难。如下:

    杭州 [0,0,0,0,0,0,0,1,0,……,0,0,0,0,0,0,0]
    上海 [0,0,0,0,1,0,0,0,0,……,0,0,0,0,0,0,0]
    宁波 [0,0,0,1,0,0,0,0,0,……,0,0,0,0,0,0,0]
    北京 [0,0,0,0,0,0,0,0,0,……,1,0,0,0,0,0,0]

    在语料库中,杭州、上海、宁波、北京各对应一个向量,向量中只有一个值为1,其余都为0。


(2) 能不能把词向量的维度变小呢?

     a) Dristributed representation:

          可以解决 One hot representation 的问题,它的思路是:

          1. 通过训练,将 每个词 都映射到一个 较短的词向量 上来。

          2. 所有的这些 词向量 就构成了 向量空间,

          3. 进而可以用 普通的统计学的方法 来研究词与词之间的关系。

          这个较短的词向量维度是多大呢?这个一般需要我们在训练时自己来指定。

      b) 举例:

          1. 比如将词汇表里的词用 "Royalty", "Masculinity", "Femininity" 和 "Age" 4个维度来表示,King 这个词对应的词向量可能是 (0.99,0.99,0.05,0.7)。

          2. 在实际情况中,并不能对词向量的每个维度做一个很好的解释。

          3. 将king这个词从一个可能非常稀疏的向量坐在的空间,映射到现在这个 四维向量 所在的空间,必须满足以下性质:

           (1)这个映射是单射;
           (2)映射之后的向量 不会丢失之前的 那种向量 所含的信息 。

          4. 这个过程称为 word embedding(词嵌入),即将高维词向量嵌入到一个低维空间。如图:

          5. 经过我们一系列的降维神操作,有了用 representation 表示的较短的词向量,我们就可以较容易的分析词之间的关系了,比如我们将词的维度降维到 2维,有一个有趣的研究表明,用下图的词向量表示我们的词时,我们可以发现:

          6. 出现这种现象的原因是,我们得到最后的词向量的训练过程中引入了词的上下文。举例:

             想到得到 "learning" 的词向量,但训练过程中,你同时考虑了它左右的上下文,那么就可以使 "learning" 带有语义信息了。通过这种操作,我们可以得到近义词,甚至 cat 和它的复数 cats 的向量极其相近。

—————— END ——————

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

one-hot Embedding 理论知识详解 + 代码实操 (为学习笔记模式,同时附完整代码)【独热向量编码】 的相关文章

  • Keras自定义损失函数的4个方法

    百度能够找出来的最原始的资源貌似是这个链接 里面提供了三种方法 但是都不能解决目前我的问题 获取是我没看懂吧 主要我的custom损失函数的参数不是简单的y true y pred 又是从中间层计算loss https spaces ac
  • 驱动篇 -- PMOS管应用

    感谢阅读本文 在接下来很长的一段时间里 我将陆续分享项目实战经验 从电源 单片机 晶体管 驱动电路 显示电路 有线通讯 无线通信 传感器 原理图设计 PCB设计 软件设计 上位机等 给新手综合学习的平台 给老司机交流的平台 所有文章来源于项

随机推荐

  • javaIO流05:FileReader和Filewriter

    FileReader FileReader是字符流 按照字符来操作io FileReader的关系继承图 2 FileReader 相关方法 new FileReader File String read 每次读取单个字符 然后返回该字符
  • 卷积的本质及物理意义(全面理解卷积)

    卷积的本质及物理意义 提示 对卷积的理解分为三部分讲解1 信号的角度2 数学家的理解 外行 3 与多项式的关系 1 来源 卷积其实就是为冲击函数诞生的 冲击函数 是狄拉克为了解决一些瞬间作用的物理现象而提出的符号 古人曰 说一堆大道理不如举
  • ChatGPT指令大全(英文版)

    ChatGPT指令大全 英文版 前言 Act as a Linux Terminal Act as an English Translator and Improver Act as position Interviewer Act as
  • WebApi 登录身份验证

    前言 Web 用户的身份验证 及页面操作权限验证是B S系统的基础功能 一个功能复杂的业务应用系统 通过角色授权来控制用户访问 本文通过Form认证 Mvc的Controller基类及Action的权限验证来实现Web系统登录 Mvc前端权
  • 将代码提交到Github代码托管平台

    本篇文章呢 阿Q将为大家讲解如何将自己的代码上传到github这个第三方代码托管平台 并更新代码 阿Q本次就以上一个Dialog的Demo为例 将其上传到github 要想上传代码到github 大家需要做一下准备工作 首先要将Git GU
  • Softmax的实现

    详解 https zhuanlan zhihu com p 25723112
  • 带icon的输入框el-input 给icon图标绑定点击事件

    element官网传送门 带icon的输入框有两种方式 选择第二种 添加点击事件
  • opengl API glCheckFramebufferStatus详解

    Name glCheckFramebufferStatus glCheckNamedFramebufferStatus check the completeness status of a framebuffer C Specificati
  • SQL解析Json字段

    MySQL支持原生JSON类型 使用JSON数据类型相较于将JSON格式的字符串存储在String型中的优势有 存储时会自动验证JSON文本 可以优化存储格式 存储在JSON型中的JSON文本会被转换成一个支持快速读取的文档元素 这样在使用
  • python基础一:计算机要点学习

    一 计算机的基本概念 1 计算机是什么 计算机是一种用于高速运算的电子机器 手机 电脑 计算器等 特点 数值计算 逻辑计算 对事物进行逻辑分析并进行判断得到的计算结果 存储记忆功能 计算机是能够按照程序运行 自动 高速处理数据的现代化电子设
  • postman几种常见的请求方式

    1 get请求直接拼URL形式 对于http接口 有get和post两种请求方式 当接口说明中未明确post中入参必须是json串时 均可用url方式请求 参数既可以写到URL中 也可写到参数列表中 都一样 请求时候都是拼URL 2 pos
  • [深入理解Android卷二 全文-第六章]深入理解ActivityManagerService

    由于 深入理解Android 卷一 和 深入理解Android卷二 不再出版 而知识的传播不应该因为纸质媒介的问题而中断 所以我将在CSDN博客中全文转发这两本书的全部内容 第6章 深入理解ActivityManagerService 本章
  • 魏副业而战:付费是最快的成长途径

    我是魏哥 与其在家躺平 不如魏副业而战 在生活中 为了提高孩子学习成绩 你会给他报辅导班 在工作中 为了提升工作效率 为了晋升 你会报课 考证书 但很少人为了自己的成长而主动付费学习 这是为什么呢 因为他没认识到付费的价值 魏哥之前也是喜欢
  • 互联网+商业模式

    大数据商业模式 10种商业模式 一 人工智能 数据 物体 智能 人工智能是数据变现的最好方式 但是目前是2B的智能买单意愿更强 GDP 20 数据是为人服务的 人接触最多的是物体 数据的智慧将延伸人的五官 拓展人的四肢 这些都依赖硬件 数据
  • 【数据结构与算法】链表OJ练习题

    作者 一只大喵咪1201 专栏 数据结构与算法 格言 你只管努力 剩下的交给时间 习题 1 移除链表元素 2 反转链表 3 链表的中间结点 4 链表中倒数第k个结点 5 合并两个有序链表 6 链表分割 7 链表的回文结构 8 相交链表 9
  • Java:求一个数组中连续子元素最大和

    public class TestArray public static int FindGreatestSumOfSubArray int array if array length 0 array null return 0 int c
  • log4j:WARN No appenders could be found for logger 解决办法

    使用log4j时不起作用 每次执行完出现以下提示 log4j WARN No appenders could be found for logger org apache ibatis logging LogFactory log4j WA
  • Linux性能分析之perf(1)基础知识总结

    Linux 09 之perf 1 基础知识总结 Author Onceday Date 2023年1月31日 漫漫长路 才刚刚开始 参考文档 Tutorial Perf Wiki kernel org linux性能分析工具专题 perf
  • FPGA-VGA协议实践

    前言 概述 VGA Video Graphics Array 视频图形阵列 是一种视频传输标准 具有分辨率高 显示速度快 颜色丰富等优点 不支持音频传输 硬件设备 FPGA开发板DE2 115 软件环境 软件环境 Quartus 一 VGA
  • one-hot Embedding 理论知识详解 + 代码实操 (为学习笔记模式,同时附完整代码)【独热向量编码】

    目 标 使用one hot Embedding 处理数据库查询语句 使其变成向量模式 以下为个人学习笔记和学习过程中用到的完整代码 环 境 腾讯云服务器 Linux系统 具体环境会在代码段前进行标注 目录 一 one hot 理论基础 二