深度神经网络语言识别

news2024/12/24 8:46:42

「AI秘籍」系列课程:

  • 人工智能应用数学基础
  • 人工智能Python基础
  • 人工智能基础核心知识
  • 人工智能BI核心知识
  • 人工智能CV核心知识

使用 DNN 和字符 n-gram 对一段文本的语言进行分类(附 Python 代码)

在这里插入图片描述

资料来源,flaticon:https://www.flaticon.com/premium-icon/cyborg_901032

语言识别是自然语言处理 (NLP) 问题中的一个重要步骤。它涉及尝试预测一段文本的自然语言。在采取其他操作(即翻译/情感分析)之前,了解文本的语言非常重要。例如,如果你使用谷歌翻译,你输入的框会显示“检测语言”。这是因为谷歌首先尝试识别你的句子的语言,然后才能翻译它。

在这里插入图片描述

语言识别有几种不同的方法,在本文中,我们将详细探讨其中一种方法。即使用神经网络和字符 n-gram 作为特征。最后,我们表明这种方法可以实现超过 98% 的准确率。在此过程中,我们将讨论关键代码,你可以在GitHub1找到完整的项目。首先,我们将讨论用于训练神经网络的数据集。

数据集

数据集2由 Tatoeba 提供。 完整数据集包含 328 种独特语言的 6,872,356 个句子。为了简化我们的问题,我们将考虑:

  • 6 种拉丁语言:英语、德语、西班牙语、法语、葡萄牙语和意大利语。
  • 长度在 20 到 200 个字符之间的句子。

我们可以在表 1 中看到每种语言的一个句子示例。我们的目标是创建一个可以使用提供的文本预测目标变量的模型。

在这里插入图片描述

我们在下面的代码中加载数据集并进行一些初始处理。我们首先过滤数据集以获取所需长度和语言的句子。我们从每种语言中随机选择 50,000 个句子,这样我们总共有 300,000 行。然后将这些句子分成训练集(70%)、验证集(20%)和测试集(10%)。

# read in full dataset
data = pd.read_csv(data_path + '/public_articles/sentences.csv', 
                            sep='\t', 
                            encoding='utf8', 
                            index_col=0,
                            names=['lang','text'])

# Filter by text length
data = data[data['text'].str.len().between(20, 200)]

# Filter by text language
lang = ['deu', 'eng', 'fra', 'ita', 'por', 'spa']
data = data[data['lang'].isin(lang)]

# Select 50000 rows for each language
data_trim_list = [data[data['lang'] == l].sample(50000, random_state=100) for l in lang]

# Concatenate all the samples
data_trim = pd.concat(data_trim_list)

# Create a random train, valid, test split
data_shuffle = data_trim.sample(frac=1, random_state=100)

train = data_shuffle[:210000]
valid = data_shuffle[210000:270000]
test = data_shuffle[270000:300000]

# Check the shapes to ensure everything is correct
print(f"Train set shape: {train.shape}")
print(f"Validation set shape: {valid.shape}")
print(f"Test set shape: {test.shape}")

特征工程

在拟合模型之前,我们必须将数据集转换为神经网络可以理解的形式。换句话说,我们需要从句子列表中提取特征来创建特征矩阵。我们使用字符 n-gram(n 个连续字符的集合)来实现这一点。这是一种类似于词袋模型的方法,只不过我们使用的是字符而不是单词。

对于我们的语言识别问题,我们将使用字符 3-grams/ trigrams (即 3 个连续字符的集合)。在图 2 中,我们看到了如何使用 trigrams 对句子进行矢量化的示例。首先,我们从句子中获取所有 trigrams 。为了减少特征空间,我们取这些 trigrams 的子集。我们使用这个子集对句子进行矢量化。第一个句子的向量是 [2,0,1,0,0],因为 trigrams “is_”在句子中出现两次,“his”出现一次。

在这里插入图片描述

创建三元特征矩阵的过程类似,但稍微复杂一些。在下一节中,我们将深入研究用于创建矩阵的代码。在此之前,有必要对如何创建特征矩阵进行总体概述。所采取的步骤如下:

  1. 使用训练集,我们从每种语言中选择了 200 个最常见的三字母组
  2. 根据这些 trigrams 创建一个唯一 trigrams 列表。这些语言共享一些共同的 trigrams ,因此我们最终得到了 661 个唯一 trigrams
  3. 通过计算每个句子中每个 trigrams 出现的次数来创建特征矩阵

我们可以在表 2 中看到此类特征矩阵的示例。顶行给出了 661 个 trigrams 中的每一个。然后,每个编号行给出了我们数据集中的一个句子。矩阵中的数字给出了该 trigrams 在句子中出现的次数。例如,“eux”在句子 2 中出现了一次。

表 2:训练特征矩阵

创建特征

在本节中,我们将介绍用于创建表 2 中的训练特征矩阵和验证/测试特征矩阵的代码。我们大量使用了SciKit Learn 提供的CountVectorizer包。此包允许我们根据一些词汇表(即单词/字符列表)对文本进行矢量化。在我们的例子中,词汇表是一组 661 个 trigrams 。

首先,我们必须创建这个词汇表。我们首先从每种语言中获取 200 个最常见的 trigrams 。这是使用下面代码中的*get_trigrams*函数完成的。此函数获取一个句子列表,并将从这些句子中返回 200 个最常见的 trigrams 的列表。

from sklearn.feature_extraction.text import CountVectorizer

def get_trigrams(corpus, n_feat=200):
    """
    Returns a list of the N most common character trigrams from a list of sentences
    params
    ------------
        corpus: list of strings
        n_feat: integer
    """
    # fit the n-gram model
    vectorizer = CountVectorizer(analyzer='char', ngram_range=(3, 3), max_features=n_feat)

    X = vectorizer.fit_transform(corpus)

    # Get model feature names
    feature_names = vectorizer.get_feature_names_out()
    return feature_names

在下面的代码中,我们循环遍历这 6 种语言。对于每种语言,我们从训练集中获取相关句子。然后我们使用get_trigrams函数获取 200 个最常见的 trigrams 并将它们添加到集合中。最后,由于这些语言共享一些共同的 trigrams ,我们得到了一组 661 个独特的 trigrams 。我们用它们来创建一个词汇表。

# obtain trigrams from each language
features = {}
features_set = set()

for l in lang:
    
    # get corpus filtered by language
    corpus = train[train.lang==l]['text']
    
    # get 200 most frequent trigrams
    trigrams = get_trigrams(corpus)
    
    # add to dict and set
    features[l] = trigrams 
    features_set.update(trigrams)

    
# create vocabulary list using feature set
vocab = dict()
for i,f in enumerate(features_set):
    vocab[f]=i

然后,CountVectorisor 包使用词汇表对训练集中的每个句子进行矢量化。结果就是我们之前看到的表 2 中的特征矩阵。

# train count vectoriser using vocabulary
vectorizer = CountVectorizer(analyzer='char',
                             ngram_range=(3, 3),
                            vocabulary=vocab)

# create feature matrix for training set
corpus = train['text']   
X = vectorizer.fit_transform(corpus)
feature_names = vectorizer.get_feature_names_out()

train_feat = pd.DataFrame(data=X.toarray(),columns=feature_names)

在训练模型之前,最后一步是缩放特征矩阵。这将有助于我们的神经网络收敛到最佳参数权重。在下面的代码中,我们使用最小-最大缩放来缩放训练矩阵。

# Scale feature matrix 
train_min = train_feat.min()
train_max = train_feat.max()
train_feat = (train_feat - train_min)/(train_max-train_min)

# Add target variable 
train_feat['lang'] = list(train['lang'])

我们还需要获取验证和测试数据集的特征矩阵。在下面的代码中,我们像对训练集所做的那样对 2 个集合进行矢量化和缩放。值得注意的是,我们使用了词汇表以及从训练集中获得的最小/最大值。这是为了避免任何数据泄露。

# create feature matrix for validation set
corpus = valid['text']   
X = vectorizer.fit_transform(corpus)

valid_feat = pd.DataFrame(data=X.toarray(),columns=feature_names)
valid_feat = (valid_feat - train_min)/(train_max-train_min)
valid_feat['lang'] = list(valid['lang'])

# create feature matrix for test set
corpus = test['text']   
X = vectorizer.fit_transform(corpus)

test_feat = pd.DataFrame(data=X.toarray(),columns=feature_names)
test_feat = (test_feat - train_min)/(train_max-train_min)
test_feat['lang'] = list(test['lang'])

探索 trigrams

现在,我们已经准备好了可用于训练神经网络的数据集。在此之前,探索数据集并建立一些直觉来了解这些特征在预测语言方面的表现会很有用。图 2 给出了每种语言与其他语言共有的 trigrams 数量。例如,英语和德语有 56 个最常见的 trigrams 是共同的。

我们发现西班牙语和葡萄牙语的共同 trigrams 最多,有 128 个共同的 trigrams。这是有道理的,因为在所有语言中,这两种语言在词汇上最相似。这意味着,使用这些特征,我们的模型可能很难区分西班牙语和葡萄牙语,反之亦然。同样,葡萄牙语和德语的共同 trigrams 最少,我们可以预期我们的模型在区分这些语言方面会更好。

图 2: trigrams 特征相似度图

建模

我们使用keras包来训练 DNN。模型的输出层使用 softmax 激活函数。这意味着我们必须将目标变量列表转换为 one-hot 编码列表。这可以通过下面的编码函数来实现。 该函数接收目标变量列表,并返回单次编码向量列表。 例如,[eng,por,por, fra,…] 将变为[[0,1,0,0,0,0],[0,0,0,0,1,0],[0,0,0,0,1,0],[0,0,1,0,0,0],…]。

from sklearn.preprocessing import LabelEncoder
from keras.utils import np_utils

# Fit encoder
encoder = LabelEncoder()
encoder.fit(['deu', 'eng', 'fra', 'ita', 'por', 'spa'])

def encode(y):
    """
    Returns a list of one hot encodings 
    
    Params
    ---------
        y: list of language labels
    """
    
    y_encoded = encoder.transform(y)
    y_dummy = np_utils.to_categorical(y_encoded)
    
    return y_dummy

在选择最终模型结构之前,我进行了一些超参数调整。我改变了隐藏层中的节点数、epoch 数和批处理大小。最终模型选择了在验证集上实现最高准确率的超参数组合。

最终模型有 3 个隐藏层,分别有 500、500 和 250 个节点。输出层有 6 个节点,每个语言一个。隐藏层都具有 ReLU 激活函数,并且如上所述,输出层具有 softmax 激活函数。我们使用 4 个 epoch 和 100 的批处理大小来训练此模型。使用我们的训练集和独热编码目标变量列表,我们在以下代码中训练此 DDN。最终,我们实现了 99.57% 的训练准确率。

from keras.models import Sequential
from keras.layers import Dense

#Get training data
x = train_feat.drop('lang',axis=1)
y = encode(train_feat['lang'])

#Define model
model = Sequential()
model.add(Dense(500, input_dim=661, activation='relu'))
model.add(Dense(500, activation='relu'))
model.add(Dense(250, activation='relu'))
model.add(Dense(6, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

#Train model
model.fit(x, y, epochs=4, batch_size=100)

模型评估

在模型训练过程中,模型可能会偏向训练集和验证集。因此,最好在未见过的测试集上确定模型准确率。测试集的最终准确率为 98.60%。这低于训练准确率 99.57%,表明发生了一些对训练集的过度拟合。

通过查看图 3 中的混淆矩阵,我们可以更好地了解模型对每种语言的表现。红色对角线表示每种语言的正确预测数。非对角线数字表示一种语言被错误预测为另一种语言的次数。例如,德语被错误预测为英语 5 次。我们发现,该模型最常将葡萄牙语混淆为西班牙语(78 次)或将西班牙语混淆为葡萄牙语(88 次)。这是我们在探索特征时看到的结果。

图 3:困惑热图

创建此混淆矩阵的代码如下所示。首先,我们使用上面训练的模型对测试集进行预测。使用这些预测语言和实际语言,我们创建一个混淆矩阵并使用 seaborn 热图对其进行可视化。

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import accuracy_score, confusion_matrix
import numpy as np

# x_test 和 y_test 已经定义,并且 model 是一个已训练好的 Keras 模型
x_test = test_feat.drop('lang', axis=1)
y_test = test_feat['lang']

# Use model.predict to get probabilities
predictions_prob = model.predict(x_test)
# Find the index of the highest probability for each sample
labels = np.argmax(predictions_prob, axis=1)
predictions = encoder.inverse_transform(labels)

# Ensure y_test is a 1D array
if y_test.ndim > 1:
    y_test = np.argmax(y_test, axis=1)

# Accuracy on test set
accuracy = accuracy_score(y_test, predictions)
print(f"Accuracy: {accuracy}")

# Create confusion matrix
lang = ['deu', 'eng', 'fra', 'ita', 'por', 'spa']
conf_matrix = confusion_matrix(y_test, predictions)
conf_matrix_df = pd.DataFrame(conf_matrix, columns=lang, index=lang)

# Plot confusion matrix heatmap
plt.figure(figsize=(10, 10), facecolor='w', edgecolor='k')
sns.set(font_scale=1.5)
sns.heatmap(conf_matrix_df, cmap='coolwarm', annot=True, fmt='.5g', cbar=False)
plt.xlabel('Predicted', fontsize=22)
plt.ylabel('Actual', fontsize=22)

plt.savefig('../figures/model_eval.png', format='png', dpi=150)
plt.show()

最后,98.60% 的测试准确率仍有提升空间。在特征选择方面,我们保持简单,只为每种语言选择了 200 个最常见的 trigrams 。更复杂的方法可以帮助我们区分更相似的语言。例如,我们可以选择在西班牙语中很常见但在葡萄牙语中不太常见的 trigrams ,反之亦然。我们还可以尝试不同的模型。希望这对你的语言识别实验来说是一个良好的起点。

参考


  1. 茶桁的公开文章项目文件 https://github.com/hivandu/public_articles ↩︎

  2. Tatoeba 数据集 https://downloads.tatoeba.org/exports/ ↩︎

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

惠海 H6225K 降压恒压芯片 支持12V24V36V48V60V转3.3V 5V车载仪器仪表方案

H6225K是一种内置60V耐压MOS,支持输入高达48V的高压降压开关控制器,可以向负载提供2.5A的连续电流。H6225K支持输出恒定电压,可以通过调节VFB采样电阻来设置输出电压,同时支持最大电流限制,可以通过修改CS采样电阻来设…

yolov8环境安装(可修改代码版本,源代码安装)

下载下来源文件以后,进去文件目录,然后输入pip指令,即可安装yolov8 cd ultralytics-main pip install -e . 直接使用pip安装的情况 当你使用pip install ultralytics这样的命令安装YOLOv8时,你实际上是在从Python包索引&#x…

HexPlane: A Fast Representation for Dynamic Scenes一种动态场景的快速表示方法

Abstract 动态三维场景的建模与再现是三维视觉领域的一个具有挑战性的课题。先前的方法基于 NERF 并依赖于隐式表示这是缓慢的,因为它需要许多 MLP 评估,限制真实世界的应用程序。我们展示了动态三维场景可以明确地表示为六个平面的学习功能&#xff0c…

[FFmpeg] windows下安装带gpu加速的ffmpeg

1.显卡能力排查 目前只有 NIVIDIA 支持 ffmpeg 的 gpu加速(AMD貌似也陆续开始支持)。 在下述网站中查找自己的显卡能够支持的编解码格式。https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-newhttps://developer.nvidia.com/video-encode-and-decod…

学习测试1

计算机基础 1、计算机范式:冯诺依曼机 2、存储单元 bit、byte、KB、MB、GB3、网络 ip、域名、ping 域名、 ipconfig测试工作的流程 ------------------------------------------------------------------------------------------- 一 编写测试大纲 罗列测试…

《昇思25天学习打卡营第10天|使用静态图加速》

文章目录 今日所学:一、背景介绍1. 动态图模式2. 静态图模式 三、静态图模式的使用场景四、静态图模式开启方式1. 基于装饰器的开启方式2. 基于context的开启方式 总结: 今日所学: 在上一集中,我学习了保存与加载的方法&#xff…

《数字图像处理-OpenCV/Python》第17章:图像的特征描述

《数字图像处理-OpenCV/Python》第17章:图像的特征描述 本书京东 优惠购书链接 https://item.jd.com/14098452.html 本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html 第17章:图像的特征描述 特征检测与匹配是计算机视觉的…

ASUS/华硕枪神4 G532L G732L系列 原厂win10系统 工厂文件 带F12 ASUS Recovery恢复

华硕工厂文件恢复系统 ,安装结束后带隐藏分区,一键恢复,以及机器所有驱动软件。 系统版本:Windows10 原厂系统下载网址:http://www.bioxt.cn 需准备一个20G以上u盘进行恢复 请注意:仅支持以上型号专用…

植物大战僵尸融合版最新版1.0下载及安装教程

《植物大战僵尸融合版》最新版1.0已经发布,为粉丝们带来了全新的游戏体验。这个版本由B站UP主蓝飘飘fly精心打造,引入了创新的植物融合玩法,让玩家可以享受策略和创意的结合。以下是游戏的详细介绍和安装指南: 游戏特色介绍 全新…

建智慧医院核心:智能导航系统的功能全析与实现效益

在数字化转型的浪潮中,智慧医院的建设是医疗行业数字化转型的关键步骤。随着医院规模的不断扩大和医疗设施的日益复杂,传统的静态不连续的导航方式已无法满足患者的需求。院内智能导航系统,作为医疗数字化转型的关键组成部分,正逐…

【ABB】控制器语言切换

【ABB】控制器语言切换 操作流程演示 操作流程 点击【菜单】点击【Control Panel】点击【Language】点击【Chinese】点击【OK】此时会弹出弹窗,点击【YES】此时控制器会重启,重启完成就是中文了 演示 点击【菜单】 点击【Control Panel】 点击【Langua…

Vue3学习笔记(n.0)

vue指令之v-for 首先创建自定义组件&#xff08;practice5.vue&#xff09;&#xff1a; <!--* Author: RealRoad1083425287qq.com* Date: 2024-07-05 21:28:45* LastEditors: Mei* LastEditTime: 2024-07-05 21:35:40* FilePath: \Fighting\new_project_0705\my-vue-app\…

c++ 里如何检测内存泄露:比如用了 new ,但没有用 delete

&#xff08;1 方法一&#xff09; 用 MFC 框架的 F5 不带断点的调试。可以在输出窗口提示是否有内存泄露。 &#xff08;2 方法二&#xff09; &#xff0c;在 main 函数中添加如下代码&#xff0c;用 F5 不带断点的调试&#xff1a; int main() {_CrtSetDbgFlag( _CRTDBG_A…

strcpy,srtcmp,strlen函数漏洞利用

strcpy,srtcmp,strlen函数漏洞利用 strcpy strcpy函数用于将字符串复制到另一个指针指向的空间中&#xff0c;遇到空字符 **b’x\00’**时停止&#xff0c;&#xff1a; 所以可以利用 strcpy不检查缓冲区 的漏洞&#xff08;构造的字符串要以\0结尾&#xff09;&#xff0c;…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【20】认证服务04—SSO单点登录

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【20】认证服务04—SSO单点登录 xxl-sso多系统-单点登录单点登录流程原理图单点登录流程简单实现参考 xxl-sso https://gitee.com/xuxueli0323/xxl-sso xxl-sso是开源的一个单点登录框架 …

hnust 1815: 算法10-6~10-8:快速排序

hnust 1815: 算法10-6~10-8&#xff1a;快速排序 题目描述 快速排序是对起泡排序的一种改进。它的基本思想是&#xff0c;通过一趟排序将待排序的记录分割成两个独立的部分&#xff0c;其中一部分记录的关键字均比另一部分的关键字小&#xff0c;在分成两个部分之后则可以分别…

C语言_操作符

目录 算术操作符 移位操作符 位操作符 赋值操作符 单目操作符 关系操作符 逻辑操作符 条件操作符 逗号表达式 下标引用&#xff0c;函数调用&#xff0c;结构成员 表达式求值 隐式类型转换 算术转换 操作符的属性 练习题 代码仓库 算术操作符 加()&#x…

WAIC上官宣!大模型语料提取工具MinerU正式发布,开源免费“敲”好用

7月4日&#xff0c;2024 WAIC科学前沿全体会议在上海世博中心红厅隆重举行。上海人工智能实验室与商汤科技联合香港中文大学和复旦大学正式发布新一代大语言模型书⽣浦语2.5&#xff08;InternLM2.5&#xff09;&#xff0c;同时全链条工具体系迎来重磅升级&#xff0c;对于大模…

17.【C语言】初识常见关键字 下

1.typedef 类型&#xff08;重新&#xff09;定义&#xff08;或命名&#xff09;&#xff0c;可简化输入 如&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> typedef signed long long k; int main() {k a 0; } signed long long被简写为k这个…

基于SpringBoot的乐校园二手书交易管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言 Java 数据库 MySQL 技术 SpringBoot框架 工具 Visual Studio、MySQL数据库开发工具 系统展示 首页 用户注册界面 二手图书界面 个人中心界面 摘要 乐校园…