当前位置: 首页 > news >正文

机械学习---词向量转化评价,附代码实例

一、词向量原理介绍

在自然语言处理(NLP)领域,词向量(Word Embedding) 是将文本中的词语转换为数值向量的技术,它解决了传统文本表示方法的局限性,为机器学习模型理解语言语义提供了基础。以下从概念、发展历程、核心原理、主流模型、应用场景等方面详细介绍词向量。

一、词向量的核心概念

词向量是词语的数值化表示,其核心思想是:将每个词语映射到一个低维稠密的实数向量空间中,使得向量之间的距离(如余弦相似度)能够反映词语的语义关联 ——语义相近的词语,其向量表示也相近

例如:

  • “国王” 和 “女王” 的向量差异,可能与 “男人” 和 “女人” 的向量差异相似;
  • “猫” 和 “狗” 的向量距离,会比 “猫” 和 “汽车” 的距离更近。

二、传统文本表示的局限性

在词向量出现之前,主流的文本表示方法存在明显缺陷,这也凸显了词向量的必要性:

  1. 独热编码(One-Hot Encoding)

    • 原理:为每个词语分配一个唯一索引,向量中仅对应索引位置为 1,其余为 0。
    • 缺陷:
      • 维度灾难:词汇表大小为 N 时,向量维度为 N(十万级),计算效率极低。
      • 语义鸿沟:向量之间是正交关系(相似度为 0),无法体现词语间的关联(如 “苹果” 和 “水果”)。
  2. 词袋模型(Bag of Words)

    • 原理:用词语的出现频率表示文本,忽略语序和语法。
    • 缺陷:丢失语义和上下文信息,高频无意义词(如 “的”“是”)会干扰模型。
  3. TF-IDF

    • 原理:通过词频(TF)和逆文档频率(IDF)加权,突出重要词语。
    • 缺陷:仍未解决语义表示问题,无法捕捉词语的多义性(如 “银行” 可指金融机构或河岸)。

三、词向量的核心原理

词向量的本质是通过上下文学习词语的语义表示,其理论基础是分布式假设(Distributional Hypothesis)

“A word is characterized by the company it keeps”(词语的语义由其上下文环境决定)。

例如,“苹果” 常出现在 “吃”“水果”“甜” 等词语附近,而 “华为” 常出现在 “手机”“科技”“品牌” 附近,通过学习这些上下文关联,模型能区分两者的语义。

四、主流词向量模型

1. Word2Vec(2013,Mikolov et al.)

Word2Vec 是最经典的词向量模型,通过简化神经网络结构实现高效训练,包含两种架构:

(1)CBOW(Continuous Bag-of-Words)

  • 原理:用上下文词语预测中心词。例如,输入 “[我] [爱] [吃] [水果]”,预测中心词 “苹果”。

  • 优势:训练速度快,适合大规模语料。

(2)Skip-gram

  • 原理:用中心词预测上下文词语。例如,输入 “苹果”,预测上下文 “我”“爱”“吃”“水果”。

  • 优势:对低频词更友好,语义表示更精准。

Word2Vec 的优化技巧

  • 负采样(Negative Sampling):通过抽样负例(非上下文词语)简化损失计算,替代传统的 softmax。

  • 层次 softmax(Hierarchical Softmax):用哈夫曼树减少输出层计算量,提升效率。

2. GloVe(Global Vectors for Word Representation,2014)

  • 原理:结合全局词共现统计局部上下文预测,通过构建词共现矩阵,用最小二乘损失优化向量表示。

  • 优势:同时利用全局统计信息和局部上下文,在语义相似度任务上表现优于 Word2Vec。

3. FastText(2016,Facebook)

  • 原理:将词语拆分为n-gram 子词(Subword),例如 “apple” 拆分为 “<ap”“app”“ppl”“ple”“le>”(< 和 > 表示边界)。

  • 优势:

    • 解决未登录词(OOV,Out-of-Vocabulary)问题:通过子词组合表示新词。

    • 对形态丰富的语言(如德语、法语)更友好。

4. 上下文相关词向量模型

传统模型(如 Word2Vec、GloVe)生成的是静态词向量(一个词对应一个向量),无法处理多义词。而上下文相关模型能根据语境动态生成向量:

(1)ELMo(Embeddings from Language Models,2018)

  • 原理:基于双向 LSTM 的预训练语言模型,为每个词语生成上下文相关向量(同一词在不同句子中向量不同)。

  • 例如:“他坐在银行边” 和 “他去银行取钱” 中,“银行” 的向量不同。

(2)BERT 及后续模型(2018 - 至今)

  • 原理:基于 Transformer 架构的预训练模型,通过 “掩码语言模型(MLM)” 和 “下一句预测(NSP)” 任务学习深层语义。

  • 优势:能捕捉更复杂的上下文依赖和语义细微差别,是当前 NLP 任务的主流基础模型。

五、词向量的训练流程

  1. 语料准备:收集大规模文本数据(如新闻、书籍、网页),进行预处理(分词、去停用词、 lowercase 等)。
  2. 词汇表构建:统计语料中出现的词语,过滤低频词,建立词汇表。
  3. 模型训练:选择 Word2Vec、GloVe 等模型,设置向量维度(通常 50-300)、窗口大小(上下文范围)等超参数,用语料训练模型。
  4. 向量应用:训练完成后,每个词语对应一个向量,可直接用于下游任务(如文本分类、相似度计算)。

六、词向量的应用场景

  1. 语义相似度计算:通过向量余弦相似度衡量词语 / 句子的语义关联(如搜索引擎中的 “相关推荐”)。
  2. 文本分类与聚类:将词向量作为特征输入分类模型(如情感分析:判断 “这部电影很棒” 为正面情绪)。
  3. 机器翻译:词向量帮助模型对齐不同语言的语义(如 “狗” 和 “dog” 的向量在空间中接近)。
  4. 问答系统与对话机器人:通过词向量理解用户问题的语义,匹配最相关的答案。
  5. 推荐系统:基于用户评论的词向量分析偏好,实现个性化推荐(如 “喜欢科幻电影的用户可能也喜欢科幻小说”)。

七、词向量的局限性与发展

局限性

  • 静态词向量无法处理多义性(如 “苹果” 既指水果也指公司)。

  • 依赖大规模高质量语料,低资源语言(如小语种)表现较差。

  • 难以捕捉复杂语义关系(如因果关系、隐喻)。

发展趋势

  • 上下文相关向量:BERT、GPT 等预训练模型成为主流,动态生成词语向量。

  • 多模态词向量:融合文本、图像、语音等信息,提升语义表示的丰富性(如 “猫” 的向量同时关联图片特征)。

  • 低资源语言优化:通过迁移学习(如用英语模型初始化小语种模型)提升效果。

总结

词向量是自然语言处理的核心技术,它将离散的词语转换为连续的向量空间表示,使机器学习模型能够 “理解” 语义。从早期的 Word2Vec 到如今的 BERT,词向量的发展推动了 NLP 任务的性能飞跃。尽管存在局限性,但词向量仍是连接文本与机器学习的重要桥梁,在各类实际应用中发挥着关键作用。

二、代码实现和实战案例

1、代码API详解

sklearn.feature_extraction.text.CountVectorizer

是 scikit-learn 库中用于将文本数据转换为词频矩阵(词向量)的核心工具,它能将一系列文本文档转换为一个基于词频计数的数值特征矩阵,是文本分类、情感分析等自然语言处理任务的基础预处理工具。

以下是其主要 API 参数和方法的详细介绍:

1、核心参数(初始化时设置)
1. 词汇表相关参数
  • input:指定输入数据的类型,默认为'content'(直接处理文本内容),可选'filename'(处理文件路径)或'file'(处理文件对象)。
  • encoding:文本编码格式,默认为'utf-8',用于读取文本时解析字符。
  • decode_error:处理编码错误的方式,默认为'strict'(报错),可选'ignore'(忽略错误)或'replace'(替换错误字符)。
  • strip_accents:是否去除字符的重音符号,可选None(不处理)、'ascii'(仅对 ASCII 字符有效)或'unicode'(对所有 Unicode 字符有效)。
  • lowercase:是否将所有文本转换为小写,默认为True,有助于统一词汇格式(如 "Hello" 和 "hello" 视为同一词)。
  • preprocessor:自定义预处理函数,用于在分词前对文本进行处理(如去除特殊符号),默认为None(使用内置处理)。
  • tokenizer:自定义分词函数,默认为None(使用内置的空格分词),中文场景中常需替换为jieba.lcut等分词工具。
  • stop_words:指定停用词表,默认为None,可选'english'(使用内置英文停用词),或传入自定义停用词列表(如中文停用词)。
  • token_pattern:分词的正则表达式模式,默认为r"(?u)\b\w\w+\b"(匹配至少 2 个字符的单词),中文场景中通常需要修改或禁用。
  • ngram_range:提取 n-gram 的范围,默认为(1, 1)(仅提取单个词),如(1, 2)表示同时提取 1-gram(单个词)和 2-gram(连续两个词)。
  • analyzer:指定分析单位,默认为'word'(按词分析),可选'char'(按字符分析)或'char_wb'(按字符分析但不跨越词边界)。
  • max_df:词的最大文档频率阈值,默认为1.0(所有文档),可设为浮点数(比例)或整数(绝对数量),过滤在过多文档中出现的词(如通用词汇)。
  • min_df:词的最小文档频率阈值,默认为1,过滤在过少文档中出现的词(如稀有词)。
  • max_features:词汇表的最大规模,默认为None(不限制),若设为整数 N,则只保留词频最高的前 N 个词。
  • vocabulary:自定义词汇表,默认为None,若传入字典({词:索引}),则仅使用该词汇表中的词。
  • binary:是否将词频转换为二进制指示(1 表示出现,0 表示未出现),默认为False(保留实际计数)。
  • dtype:输出矩阵的数据类型,默认为numpy.int64,可改为numpy.float32等节省内存。
2、核心方法
  1. fit(raw_documents)

    • 功能:根据输入的文本数据(raw_documents)构建词汇表,统计词频并确定最终保留的词。
    • 输入:文本列表(如["我喜欢python", "python很强大"])。
    • 输出:返回对象本身(可链式调用)。
  2. transform(raw_documents)

    • 功能:使用已构建的词汇表,将输入文本转换为词频矩阵(稀疏矩阵)。
    • 输入:与fit相同格式的文本列表。
    • 输出:形状为(n_samples, n_features)的稀疏矩阵,其中n_samples为文本数量,n_features为词汇表大小,矩阵值为词在文本中的出现次数(或二进制指示)。
  3. fit_transform(raw_documents)

    • 功能:合并fittransform步骤,先构建词汇表,再直接转换文本,效率高于单独调用。
  4. get_feature_names_out()

    • 功能:返回词汇表中的所有词(按索引顺序),用于查看构建的词汇表内容。
    • 输出:数组形式的词列表(如array(['python', '喜欢', '强大'], dtype=object))。
  5. inverse_transform(X)

    • 功能:将词频矩阵转换回文本形式(仅保留出现的词)。
    • 输入:由transform生成的词频矩阵。
    • 输出:文本列表,每个元素为对应文档中出现的词(用空格连接)。
  6. get_params(deep=True)

    • 功能:获取当前CountVectorizer的所有参数配置。
  7. set_params(**params)

    • 功能:修改CountVectorizer的参数配置(如动态调整max_features)。
3、注意事项
  • 中文处理:CountVectorizer默认按空格分词,中文需先使用jieba等工具分词,再用空格连接(如"我 喜欢 机器学习"),并设置tokenizer=lambda x: x.split()
  • 内存问题:文本量大时,词频矩阵可能非常稀疏,建议保留稀疏矩阵格式(避免用toarray()转换为稠密矩阵)。
  • 词汇表规模:通过max_dfmin_dfmax_features控制词汇表大小,避免维度灾难。

2、实战案例(好评差评的判断)

现在需要用词向量的方法来训练一个好评差评的分析模型,

数据就用爬虫爬取的苏宁易购的数据

教程:看爬取的第二个案例

如果不想麻烦可以直接下载,数据已经上传(完整的工程文件也已经上传)

代码详解:

1. 导入库

import pandas as pd

这行代码导入了pandas库,并将其别名为pdpandas是一个用于数据处理和分析的强大库,在后续代码中用于读取文件、数据处理和构建数据框等操作。

2. 读取数据并分词

cp = pd.read_table("差评.txt", encoding='gbk')
yzpj = pd.read_table("优质评价.txt", encoding='gbk')import jieba
cp_segments = []
contents = cp.content.values.tolist()
for content in contents:results = jieba.lcut(content)if len(results)>1:cp_segments.append(results)
cp_fc_results = pd.DataFrame({'content':cp_segments})
cp_fc_results.to_excel('cp_fc_results.xlsx',index = False)yzpj_segments = []
contents = yzpj.content.values.tolist()
for content in contents:results = jieba.lcut(content)if len(results)>1:yzpj_segments.append(results)
yzpj_fc_results = pd.DataFrame({'content':yzpj_segments})
yzpj_fc_results.to_excel('yzpj_fc_results.xlsx',index = False)
  • 首先使用pd.read_table函数分别读取了名为 “差评.txt” 和 “优质评价.txt” 的文件,文件编码为gbk,并将数据存储在cpyzpj两个数据框中。
  • 然后导入jieba库,这是一个中文分词工具。
  • 接下来通过循环遍历cp数据框中content列的值,使用jieba.lcut对每个评价内容进行分词,将分词结果长度大于 1 的添加到cp_segments列表中,最后将cp_segments列表转换为数据框cp_fc_results并保存为cp_fc_results.xlsx文件。
  • yzpj数据框进行同样的操作,得到分词后的结果并保存为yzpj_fc_results.xlsx文件。

3. 去除停用词

stopwords = pd.read_csv('StopwordsCN.txt',encoding='utf-8',engine='python',sep='\t')
def drop_stopwords(contents,stopwords):segments_clean = []for content in contents:line_clean = []for word in content:if word in stopwords:continueline_clean.append(word)segments_clean.append(line_clean)return segments_cleancontents = cp_fc_results.content.values.tolist()
stopwords = stopwords.stopword.values.tolist()
cp_fc_content_clean_s = drop_stopwords(contents,stopwords)contents = yzpj_fc_results.content.values.tolist()
yzpj_fc_content_clean_s =drop_stopwords(contents,stopwords)
  • 首先使用pd.read_csv函数读取了名为 “StopwordsCN.txt” 的停用词文件,文件编码为utf - 8,使用python引擎,分隔符为制表符\t
  • 定义了drop_stopwords函数,该函数接受两个参数,contents是包含分词结果的列表,stopwords是停用词列表。函数内部通过嵌套循环遍历contents中的每个分词结果和其中的每个单词,如果单词在停用词列表中则跳过,否则将其添加到line_clean列表中,最后将line_clean列表添加到segments_clean列表中并返回。
  • 分别将cp_fc_resultsyzpj_fc_results数据框中content列的值转换为列表,然后调用drop_stopwords函数去除停用词,得到cp_fc_content_clean_syzpj_fc_content_clean_s两个去除停用词后的列表。

4. 朴素贝叶斯分类

4.1 给每个数据添加数字标签
cp_train = pd.DataFrame({'segments_clean': cp_fc_content_clean_s, 'label': 1})
yzpj_train = pd.DataFrame({'segments_clean': yzpj_fc_content_clean_s, 'label': 0})
pj_train = pd.concat([cp_train, yzpj_train])
pj_train.to_excel('pj_train.xlsx', index=False)
  • 将去除停用词后的差评数据cp_fc_content_clean_s和标签1(表示差评)构建成数据框cp_train,将优质评价数据yzpj_fc_content_clean_s和标签0(表示优质评价)构建成数据框yzpj_train
  • 使用pd.concat函数将cp_trainyzpj_train两个数据框合并成一个数据框pj_train,并将其保存为pj_train.xlsx文件。
4.2 数据切分
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = \train_test_split(pj_train['segments_clean'].values, pj_train['label'].values, random_state=0)

sklearn.model_selection模块中导入train_test_split函数,该函数用于将数据集划分为训练集和测试集。这里将pj_train数据框中的segments_clean列的值作为特征数据,label列的值作为标签数据,按照默认的测试集比例将数据划分为训练集特征x_train、测试集特征x_test、训练集标签y_train和测试集标签y_testrandom_state = 0用于设置随机种子,确保每次运行代码时数据划分结果一致。

4.3 将所有的词转换为词向量
words = []
for line_index in range(len(x_train)):words.append(' '.join(x_train[line_index]))from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(max_features=10000, lowercase=False, ngram_range=(1, 3))
vec.fit(words)
x_train_vec = vec.transform(words)
  • 首先创建一个空列表words,通过循环将训练集特征x_train中的每个分词结果列表转换为以空格分隔的字符串,并添加到words列表中。
  • sklearn.feature_extraction.text模块中导入CountVectorizer类,该类用于将文本数据转换为词向量。创建CountVectorizer对象vec,设置max_features = 10000表示只提取词频最高的前 10000 个词作为词库,lowercase = False表示不将所有词转换为小写,ngram_range=(1, 3)表示考虑 1 - 3 元组的词。
  • 使用vec.fit(words)根据words列表构建词向量模型,然后使用vec.transform(words)words列表转换为词向量矩阵x_train_vec
4.4 训练朴素贝叶斯分类器并进行预测
from sklearn.naive_bayes import MultinomialNB, ComplementNB
classifier = MultinomialNB(alpha=0.1)
classifier.fit(x_train_vec, y_train)train_pr = classifier.predict(x_train_vec)from sklearn.metrics import accuracy_scoretest_words = []
for line_index in range(len(x_test)):test_words.append(' '.join(x_test[line_index]))
x_test_vec = vec.transform(test_words)test_pr = classifier.predict(x_test_vec)
print("测试集准确率:", accuracy_score(y_test, test_pr))
test_predicted = classifier.predict(x_test_vec)
print("测试集分类报告:")
print(metrics.classification_report(y_test, test_predicted, digits=4))
  • sklearn.naive_bayes模块中导入MultinomialNBComplementNB类,这里选择MultinomialNB类创建朴素贝叶斯分类器对象classifier,设置alpha = 0.1
  • 使用classifier.fit(x_train_vec, y_train)对分类器进行训练,将训练集词向量x_train_vec和训练集标签y_train作为训练数据。
  • 使用classifier.predict(x_train_vec)对训练集进行预测,得到训练集预测结果train_pr
  • 对测试集数据进行同样的处理,先将测试集特征x_test转换为以空格分隔的字符串列表test_words,然后转换为词向量矩阵x_test_vec,使用classifier.predict(x_test_vec)对测试集进行预测,得到测试集预测结果test_pr
  • 使用accuracy_score函数计算测试集的准确率并打印,使用classification_report函数生成测试集的分类报告并打印,digits = 4表示保留四位小数。
4.5 交互式预测
while True:text_something = input('请输入一段评价(输入exit退出):')if text_something == 'exit':breakseg_list = jieba.lcut(text_something)seg_clean = [word for word in seg_list if word not in stopwords]text_processed = [' '.join(seg_clean)]text_vec = vec.transform(text_processed)predict = classifier.predict(text_vec)if predict[0] == 1:print("预测结果:差评")else:print("预测结果:优质评价")
  • 使用while True创建一个无限循环,在循环内部使用input函数获取用户输入的评价文本。
  • 如果用户输入的是exit,则使用break跳出循环。
  • 否则,对用户输入的文本进行分词、去除停用词处理,将处理后的结果转换为符合要求的格式并转换为词向量,最后使用训练好的分类器进行预测,并根据预测结果打印 “预测结果:差评” 或 “预测结果:优质评价”。

http://www.dtcms.com/a/333754.html

相关文章:

  • 力扣(接雨水)——单调栈
  • 第454题.四数相加II
  • JavaWeb开发_Day12
  • 基于Selenium的web自动化框架
  • 电视同轴电缆全面指南:从基础到应用,批量测量一键计量
  • 第四章:大模型(LLM)】06.langchain原理-(2)langchain Chain的使用方法
  • 力扣top100(day04-03)--二分查找
  • MqSQL中的《快照读》和《当前读》
  • [论文笔记] WiscKey: Separating Keys from Values in SSD-Conscious Storage
  • Linux core dump
  • Flutter开发 webview_flutter的基本使用
  • MC0423铺砖块
  • Linux系统编程—Linux基础指令
  • OpenCV Python——图像查找(特征匹配 + 单应性矩阵)
  • Linux软件编程(五)(exec 函数族、system、线程)
  • SQL:生成日期序列(填补缺失的日期)
  • 磁悬浮轴承“幽灵振动”克星:深度解析同频振动机理与精准打击策略
  • 优先级反转问题
  • [Python 基础课程]根据描述定义一个 Person 类
  • 关注与优化:用于骨龄评估的交互式关键点定位与颈椎定量分析|文献速递-深度学习人工智能医疗图像
  • Go语言中的指针接收者
  • 语音活动检测VAD技术简介
  • 崩溃大陆2 送修改器 PC/手机双端(Crashlands2)免安装中文版
  • Fanuc机器人EtherCAT通讯配置详解
  • 思科应用中心基础设施(ACI)设计指南
  • Redis面试精讲 Day 22:Redis布隆过滤器应用场景
  • 第2篇_Go语言基础语法_变量常量与数据类型
  • Java-JVM是什么JVM的类加载机制
  • 设备 AI 知识库,管理效率新飞跃
  • 安装openmmlab时出错