自然语言处理(NLP)—— 语言检测器

 1. 文章概述

1.1 目的

        在本篇文章中,我们将构建一个语言检测器,这是一个能够识别文本语言的简单分类器。这是一个能够识别文本是用哪种语言写的程序。想象一下,你给这个程序一段文字,它就能告诉你这是英语、法语还是其他语言。

1.2 方法

        遵循频率主义者的方法,我们从零开始,几乎不假设任何关于语言的先验知识,甚至不假设单词或标记的存在。我们仅考虑构成文本的符号——Unicode字符,以及它们出现的排列。我们使用的方法叫做“朴素贝叶斯分类”。它的工作方式是通过观察文本中字母或符号的组合(我们称之为“n-gram”),因为不同的语言中这些组合的出现频率是不同的。比如说,某些字母组合在法语中很常见,但在英语中可能就很罕见。为此,我们将简单地计算字符n-gram的频率。我们的假设是,字符n-gram的分布远非随机,并且每种语言都不同:它提供了一种语言的签名。我们将通过使用(甚至构建)一个简单的朴素贝叶斯分类器来测试这一假设。

1.3 示例

        如果我们有一段法文“ÉLÈVE ÈVE”,我们会注意到其中一些字母组合,比如“ÉLÈ”、“LÈV”、“ÈVE”等出现的次数。我们的程序会用这些信息来判断文本的语言。例如,法文文本"ÉLÈVE ÈVE"将包含以下的三元组计数(‘_’表示空格):

        ÉLÈ: 1
        LÈV: 1
        ÈVE: 2
        VE_: 1
        E_È: 1
        _ÈV: 1

        三元组计数(trigram counting)是一种文本分析方法,用于统计和分析文本中每个连续的三个字符(或字母)出现的频率。这种方法把文本分成许多三个字符的组合(或称为“三元组”),然后计算每种组合在文本中出现的次数。三元组计数是自然语言处理(NLP)中常用的一种特征提取技术,尤其在语言识别、拼写检查和文本生成等任务中非常有用。

        举个例子,对于文本“hello”,其三元组及其计数如下:

        “hel”:1次
        “ell”:1次
        “llo”:1次

        通过对不同语言的文本进行三元组计数,我们可以得到这些语言字符组合的频率分布。由于每种语言都有其特定的字符组合习惯,这些频率分布可以作为识别语言的依据。在朴素贝叶斯分类器中,这些三元组的频率数据会被用来预测文本所属的语言,即通过分析文本中的三元组出现频率来判断这段文本最可能是哪种语言。

1.4 朴素贝叶斯分类

        朴素贝叶斯分类中的“朴素”意味着分类器将所有特征视为独立它认为遇到ÉLÈ与遇到LÈV是独立的,这在语言中显然不是这样,但它是构建简单模型的一个方便假设。“贝叶斯”则是指贝叶斯定理:


P(y|x) = \frac{P(x|y)P(y)}{P(x)}


        在我们的案例中,x = x_1, x_2, ..., x_n代表我们的n-gram观察值,y是一种语言。P(y|x)预测给定输入三元组x时,语言是y的概率。

        实际操作中,由于“朴素”属性,P(x|y)计算为P(x_1|y)...P(x_n|y)。另外,在分类时,我们省略计算分母P(x),因为它在各个类别中是常数(与y无关),因此不改变最终结果。我们的朴素贝叶斯分类器将简单地计算:
        每种语言的单独n-gram频率(例如P(x = EVE|y = French),ÈVE在法文、英文、印尼语等中出现的频率);
        训练语料库中法文、英文等n-gram的比例:P(y = French)

1.5 实现这个语言检测器的步骤

        a.收集数据:首先,我们需要不同语言的文本数据。这些文本包含了我们想要识别的语言。

        b.提取特征:然后,我们从这些文本中提取“n-gram”。比如,我们可以看每三个字母的组合出现了多少次。这些统计数据帮助我们理解每种语言的特点。

        c.训练分类器:有了这些数据后,我们就可以训练我们的程序了。训练就是让程序学习不同语言的n-gram频率模式。

        d.预测语言:一旦训练完成,我们就可以给程序任何一段文本,它会使用它学到的知识来告诉我们这段文本是什么语言。

        简而言之,我们的目标是创建一个能够通过查看文本中字母组合的频率来判断语言的程序。

2. 现在让我们开始实验吧!

2.1 准备阶段

        在这个练习中,你将使用Python进行编程。为了完成这个任务,你需要安装几个Python库,包括`numpy`、`scikit-learn`和(可选的)`nltk`。这些库可以通过以下命令安装:

pip install numpy

        安装numpy,一个用于科学计算的库,支持大量的维度数组和矩阵运算,此外还提供了大量的数学函数库。

pip install scikit-learn

        安装scikit-learn,一个用于机器学习的库。提供了许多不同的算法和工具来进行数据挖掘和数据分析。

pip install nltk

        安装nltk,自然语言处理工具包,用于处理人类语言数据的库。

这个练习将使用两个语料库:
        easy corpus包含10种语言,每种语言有10,000个训练句子和1,000个评估句子。
        challenging corpus包含75种语言,每种语言仅有900个训练句子和100个评估句子。

        第二个语料库更具挑战性,因为对于更多的目标类别(语言),训练数据要少得多。

        代码可在绑定资源里下载。

2.2 初步探索

        要进行这项初步探索,我们将编写一些简单的Python代码来分析语料库中的n-gram频率。这段代码将计算每种语言的唯一n-gram数量,并显示每种语言20个最常见的n-gram。n-gram的大小(数字n)将是代码中的一个可修改参数,这样你就可以用单个字符(unigrams)、两个字符(bigrams)、三个字符(trigrams)、四个字符(quadrigrams)等来试验。

        首先,我将展示一个简化的代码示例,用于计算和显示n-gram的频率。这个例子将使用Python标准库来处理文本,而不是`nltk`,这样我们可以更清楚地看到底层逻辑。然后,我会展示如何使用`nltk`的`FreqDist`类来完成同样的任务。

2.2.1 使用Python标准库

        我们将从基本的文本处理开始,提取n-gram并计算它们的频率。

def generate_ngrams(text, n=2):ngrams = [text[i:i+n] for i in range(len(text)-n+1)]return ngramsdef ngram_frequencies(texts, n=2):from collections import Counterngrams_all = []for text in texts:ngrams = generate_ngrams(text, n)ngrams_all.extend(ngrams)return Counter(ngrams_all)

        假设texts是一个包含多种语言文本的字典,其中键是语言名称,值是该语言的文本列表

        示例: texts = {'English': ['This is a sentence.', ...], 'French': ['Ceci est une phrase.', ...]}

        下面是如何使用这个函数并打印每种语言20个最常见的n-gram

n = 3  # 你可以修改这个参数来探索不同的n-gram大小
for language, text_list in texts.items():fdist = ngram_frequencies(text_list, n)print(f"{language} - Top 20 n-grams: {fdist.most_common(20)}")

2.2.2 使用`nltk`的`FreqDist`

        如果你选择使用`nltk`,代码会更简洁,因为`FreqDist`类已经为我们处理了频率计算。

import nltk
from nltk.probability import FreqDistdef ngram_frequencies_nltk(texts, n=2):ngrams_all = []for text in texts:ngrams = nltk.ngrams(text, n)ngrams_all.extend(ngrams)return FreqDist(ngrams_all)# 使用nltk的FreqDist
for language, text_list in texts.items():texts_combined = " ".join(text_list)  # 将所有文本合并为一个长字符串fdist = ngram_frequencies_nltk(texts_combined, n)print(f"{language} - Top 20 n-grams: {fdist.most_common(20)}")

        这两种方法都可以用来探索n-gram的频率分布。

        n-gram数量随n的增加而指数增长,因为组合的可能性会大大增加。

        比较不同语言最常见的n-gram可以揭示语言之间的相似性和差异性。

        对于一些特定的n-gram,它们可能在多种语言中都很常见,而其他一些则可能是某特定语言特有的,这些差异对于构建语言检测模型特别有用。

2.2.3 最终代码

        计算每种语言的唯一n-gram数量,并显示每种语言20个最常见的n-gram。

2.3 基于 Scikit 的分类

        Scikit 为我们做了一切。它的 CountVectorizer 类提取 n-grams 并计算其出现次数。

        出现的次数。MultinomialNB 类则根据 n-gram 计数计算似然值,用于训练、和语言类别概率进行预测。

  1. 查看 langdetect_scikit.py 的源代码。
  2. 在 "easy "语料库上运行 langdetect_scikit.py,n-gram 的大小从 1 开始依次增加。记下结果。理想的 n-gram 大小是多少?
  3. 注意 CountVectorizer 的参数。如果去掉重音(设置为 "unicode"),结果会怎样?(设置为 "unicode")?如果我们将文本转换为小写?
  4. 您还可以尝试去掉标点符号和数字:这有帮助吗?
  5. 在 "具有挑战性 "的语料库上也做几次测试,然后比较结果。

3. 布朗语料库的某些方面

3.1 先决条件

        要在没有 root 用户的情况下安装 NLTK,您可以编写以下命令

pip install nltk --user

        然后,为了加载我们需要的语料库,我们将以交互模式启动 Python,并写下

python
>>> import nltk
>>> nltk.download()

        在打开的窗口中,如果没有配额问题,在 "Collections "中选择 "All",或者选择 "Book",然后点击 "Donwload"。完成操作后,按 Ctrl-D 键退出交互模式。
将使用以下模块:

import nltk
from nltk.corpus import brown
from nltk.probability import FreqDist
import re

        您可以使用

brown.tagged_words()

        方法获取布朗语料库中的所有单词及其 POS 标记元组。

NLTK :: Installing NLTK Data

        您可以从 nltk 网页上https://www.nltk.org/book/ch02.html获取更多有关通过常规方法访问语料库的信息。

3.2 问题和答案

        a) 在布朗的语料库中,哪些名词的复数比单数更常见?复数

        认为复数只需加上一个 "s "即可构成)。按复数形式的出现频率和复数/单数形式的出现频率对前 20 个结果进行分类。
        按复数形式的频率和复数/单数的比例对前 20 个结果进行分类。

        b) 哪个单词有最多的不同标记?它们代表什么?

        c) 按频率降序列出标签(前 20 个)。它们代表什么?

        d) 名词前面最常见的标记是什么?它们代表什么?

4 标记器评估

4.1 基于 POS 的 POS 标记

        在本节中,我们将创建标记符(默认标记符为 nltk.DefaultTagger,the n-grams tagger, nltk.NgramTagger),并使用布朗语料库中的新闻类别对它们进行训练。

        我们将使用布朗语料库中的新闻类别对它们进行训练。

        进行十倍交叉验证。

        使用简化标签集评估相同的标记符。

4.2 基于内在属性的给定名称性别标签

        在本节中,我们将使用模块

import nltk
from nltk.corpus import names
import random
import collections

        姓名语料库由两个文件组成:female.txt 和 male.txt。创建一个元组列表(给定名称、性别)的随机顺序。统计上位混合名。
        在上一节中,我们使用了单词和标签。在这里,我们将采用一种更通用的方法:我们将定义属性,并评估这些属性对分类任务的贡献(在我们的案例中:给定姓名的性别)。在我们的例子中:给定名字的性别)的贡献。第一个候选属性:最后一个字母。

def gender_features(word):return {'last_letter': word[-1]}
featuresets = [(gender_features(n), g) for (n,g) in names]
train_set, test_set = featuresets[500:], featuresets[:500]
classifier = nltk.NaiveBayesClassifier.train(train_set)
print(nltk.classify.accuracy(classifier, test_set))

        我们得到的就是准确率。同时计算每个性别的精确度、召回率和 F-measure(使用
使用 nltk.metrics 的同名方法,注意:要使用这些方法,您必须将给定名字的数量收集到列表中。
注意:要使用这些方法,您必须根据排名和真实性别收集列表中给定名字的数量)。我们发现了什么?
        使用 classify 的 show_most_informative_features(10) 方法,我们可以找出
属性的值。
        要想尝试新的属性,可以编写代码来显示所有分类错误的代码,并为每个错误显示正确的类别、错误的类别和名称。

        测试其他属性及其组合。

5. 使用NLTK进行名字性别分类

        在本章中,我们将使用Python的Natural Language Toolkit(NLTK)库来分析和分类名字的性别,基于名字的内在属性。我们将通过几个步骤来完成这个任务:

5.1 导入模块和数据

        首先,我们需要导入所需的模块,并从NLTK的名字语料库中加载男性和女性的名字。这些名字将被存储在两个分别包含男性和女性名字的文件中。

import nltk
from nltk.corpus import names
import random
import collections# 确保已下载名字数据集
nltk.download('names')# 加载男性和女性的名字
male_names = names.words('male.txt')
female_names = names.words('female.txt')

5.2 创建名字和性别的元组列表

        接着,我们将这些名字和对应的性别标签('male' 或 'female')组合成元组,然后将这些元组随机排序,以便后续的数据分割和分析。

# 创建名字和性别的元组列表,并随机排序
names = [(name, 'male') for name in male_names] + [(name, 'female') for name in female_names]
random.shuffle(names)

5.3 定义特征提取函数

        为了分类任务,我们定义一个函数 `gender_features`,该函数基于名字的内在属性来提取特征。在这个例子中,我们使用的第一个属性是名字的最后一个字母。

# 定义特征提取函数
def gender_features(word):return {'last_letter': word[-1]}

5.4 创建特征集

        使用 `gender_features` 函数,我们为每个名字提取特征,并将这些特征与相应的性别标签组合成特征集。

# 创建特征集
featuresets = [(gender_features(n), g) for (n, g) in names]

5.5 分割数据集

        我们将特征集分为训练集和测试集,用于训练和评估模型。

# 分割数据集
train_set, test_set = featuresets[500:], featuresets[:500]

5.6 训练分类器

        使用训练集,我们训练一个Naive Bayes分类器。

# 训练分类器
classifier = nltk.NaiveBayesClassifier.train(train_set)

5.7 评估分类器

        评估分类器在测试集上的准确性,并计算精确度(precision)、召回率(recall)和F-度量(F-measure)等性能指标。

# 计算并打印分类器的准确性
accuracy = nltk.classify.accuracy(classifier, test_set)
print(f'Accuracy: {accuracy:.2f}')# 收集预测和真实的性别标签
test_truth = [label for (features, label) in test_set]
test_pred = [classifier.classify(features) for (features, label) in test_set]# 计算精确度、召回率和F-度量
def get_metrics(truth, pred, label):tp = sum(1 for t, p in zip(truth, pred) if t == label and p == label)fp = sum(1 for t, p in zip(truth, pred) if t != label and p == label)fn = sum(1 for t, p in zip(truth, pred) if t == label and p != label)precision_val = tp / (tp + fp) if tp + fp > 0 else 0recall_val = tp / (tp + fn) if tp + fn > 0 else 0f_measure_val = 2 * precision_val * recall_val / (precision_val + recall_val) if precision_val + recall_val > 0 else 0return precision_val, recall_val, f_measure_valprecision_male, recall_male, f_measure_male = get_metrics(test_truth, test_pred, 'male')
precision_female, recall_female, f_measure_female = get_metrics(test_truth, test_pred, 'female')print(f"Precision (male): {precision_male:.2f}")
print(f"Recall (male): {recall_male:.2f}")
print(f"F-measure (male): {f_measure_male:.2f}")print(f"Precision (female): {precision_female:.2f}")
print(f"Recall (female): {recall_female:.2f}")
print(f"F-measure (female): {f_measure_female:.2f}")

5.8 显示最有信息量的特征

        通过 `show_most_informative_features` 方法,我们可以了解哪些属性对于性别分类最有判别力。

# 显示最有信息量的特征
classifier.show_most_informative_features(10)

5.9. 分析分类错误

        编写代码来展示分类错误,为每个错误提供正确的类别、错误选择的类别和名字。

# 分析分类错误
errors = []
for (name, tag) in names[:500]:guess = classifier.classify(gender_features(name))if guess != tag:errors.append((tag, guess, name))print("Errors:")
for (tag, guess, name) in sorted(errors):print(f"correct={tag} guess={guess} name={name}")

5.10 测试其他属性和它们的组合

        探索除了名字的最后一个字母之外的其他属性,以及它们对分类任务的影响。

# 测试其他特征
def gender_features_extended(word):return {'last_letter': word[-1],'first_letter': word[0],'length': len(word),'last_two': word[-2:]}# 创建扩展特征集
extended_featuresets = [(gender_features_extended(n), g) for (n, g) in names]
train_set_extended, test_set_extended = extended_featuresets[500:], extended_featuresets[:500]# 训练扩展特征集上的分类器
classifier_extended = nltk.NaiveBayesClassifier.train(train_set_extended)# 计算并打印扩展特征集分类器的准确性
accuracy_extended = nltk.classify.accuracy(classifier_extended, test_set_extended)
print(f'Extended Features Accuracy: {accuracy_extended:.2f}')# 显示扩展特征集上最有信息量的特征
classifier_extended.show_most_informative_features(10)

5.11 总结

        通过这些步骤,我们能够使用NLTK库构建一个简单但有效的名字性别分类器。我们从名字的最后一个字母开始提取特征,逐步扩展到包括更多的属性,并对分类器进行了训练和评估。通过这种方式,我们不仅实现了名字性别的分类,还探索了不同特征组合对分类性能的影响。这为进一步优化分类模型提供了基础,也展示了NLTK在自然语言处理任务中的强大功能。

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

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

相关文章

C语言过度C++语法补充(面向对象之前语法)

目录 1. C相较于C语言新增的语法 0. C 中的输入输出 1. 命名空间 1. 我们如何定义一个命名空间? 2. 如何使用一个命名空间 3. 命名空间中可以定义什么? 4. 在 相同或者不同 的文件中如果出现 同名的命名空间 会如何? 5. 总结~~撒花~~…

优维「Easy分析」:一款故障根因分析小神器

背 景 随着微服务架构的普及,现代企业的IT基础设施已经变得越来越复杂。单一的服务可能有多个下游依赖,而这些依赖又可能有自己的子依赖,和主机资源的依赖。在这样的环境中,当某个服务发生故障,确定具体的原因变得尤为…

【Linux】The server quit without updating PID file的几种解决方案

😎 作者介绍:我是程序员洲洲,一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主。 🤓 同时欢迎大家关注其他专栏,我将分享Web前后端开发、人工智能、机器学习、深…

微服务架构-微服务实施

目录 一、概述 二、微服务拆分 2.1 概述 2.2 拆分原则 2.3 拆分方法 2.3.1 以数据为维度进行拆分 2.3.2 按照使用场景拆分 2.3.3 重要和非重要的拆分 2.3.4 变和不变的拆分 三、微服务通信 3.1 概述 3.2 微服务通信方式选择 3.3 微服务编排 3.4 API接口设计 3.5 …

C++基础与深度解析 | 类与面向对象编程 | 数据成员 | 成员函数 | 访问限定符与友元 | 构造、析构成员函数 | 字面值类、成员指针与bind交互

文章目录 一、结构体与对象聚合二、成员函数(方法)三、访问限定符与友元1.访问限定符2.友元(慎用) 四、构造、析构与复制成员函数1.构造函数2.析构函数3.补充 五、字面值类,成员指针与bind交互1.字面值类2.成员指针3.b…

【MATLAB源码-第224期】基于matlab的快跳频系统仿真采用4FSK,模拟了单音干扰,宽带干扰以及部分频带干扰,输出误码率曲线以及各节点图像。

操作环境: MATLAB 2022a 1、算法描述 跳频通信系统概述 跳频通信系统是一种通过快速切换载波频率来进行信息传输的无线通信技术。它在军事和商业通信中广泛应用,具有较强的抗干扰和抗截获能力。系统设计主要包括信号调制、跳频序列生成、信道模拟以及…

Java 初识

Java 的发展历程 Sun 公司。 Oracle 公司。 普通版本,也叫过渡版本。 正式版本,也叫长期支持版本(LTS)。 Java SE,Java EE,Java ME Java 技术体系分为三个平台:Java SE,Java EE&a…

G5 - Pix2Pix理论与实战

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目录 理论知识图像翻译CGANU-NetPix2Pix损失函数模型结构生成器差别器 模型效果总结与心得体会 理论知识 前面已经学习了GAN与CGAN,这节开始学习P…

记一次Linux下Docker镜像服务器磁盘空间清理

我们开发环境Jenkins构建项目时报服务器磁盘空间不足,导致项目自动化构建部署失败, Docker镜像服务器磁盘空间清理我们做了多次了,之前在清理Docker镜像服务器时走了不少弯路,查了不少Docker镜像服务器空间清理,都大同…

AI大数据处理与分析实战--体育问卷分析

AI大数据处理与分析实战–体育问卷分析 前言:前一段时间接了一个需求,使用AI进行数据分析与处理,遂整理了一下大致过程和大致简要结果(更详细就不方便放了)。 文章目录 AI大数据处理与分析实战--体育问卷分析一、数据…

部署kubesphere报错

安装kubesphere报错命名空间terminted [rootk8smaster ~]# kubectl apply -f kubesphere-installer.yaml Warning: apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16, unavailable in v1.22; use apiextensions.k8s.io/v1 CustomResourceDefini…

LabVIEW阀性能试验台测控系统

本项目开发的阀性能试验台测控系统是为满足国家和企业相关标准而设计的,主要用于汽车气压制动系统控制装置和调节装置等产品的综合性能测试。系统采用工控机控制,配置电器控制柜,实现运动控制、开关量控制及传感器信号采集,具备数…

【数据结构初阶】--- 顺序表

顺序表,好像学C语言时从来没听过,实际上就是给数组穿了层衣服,本质是一模一样的。 这里的顺序表实际是定义了一个结构体,设计各种函数来实现它的功能,比如说数组中的增删改查插入,这些基本操作其实平时就会…

go语言内置预编译 //go:embed xxx 使用详解

在go语言里面,我们可以使用一个“类注释”的语法来来让编译器帮助我们在编译的时候将一些文件或者目录读取到指定的变量中来供我们使用。 go:embed语法: //go:embed 文件或者目录路径 var 变量名 变量类型 说明: 文件或者目录路径 可以…

【操作系统】进程与线程的区别及总结(非常非常重要,面试必考题,其它文章可以不看,但这篇文章最后的总结你必须要看,满满的全是干货......)

目录 一、 进程1.1 PID(进程标识符)1.2 内存指针1.3 文件描述符表1.4 状态1.5 优先级1.6 记账信息1.7 上下文 二、线程三、总结:进程和线程之间的区别(非常非常非常重要,面试必考题) 一、 进程 简单来介绍一下什么是进程&#xf…

C++学习/复习13--list概述

一、list概念 1.带头双向链表 2.构造函数 3.迭代器(其迭代器需尤其注意) 4、size 5.front/back 6.插入删除 删除时的迭代器失效 由于list的节点特殊,既有数据又有指针,其实现需要节点/迭代器/list各成一类再组合

Windows系统电脑本地部署AI音乐创作工具并实现无公网IP远程使用

文章目录 前言1. 本地部署2. 使用方法介绍3. 内网穿透工具下载安装4. 配置公网地址5. 配置固定公网地址 前言 本文主要介绍如何在Windows系统电脑上快速本地部署一个文字生成音乐的AI创作工具MusicGPT,并结合cpolar内网穿透工具实现随时随地远程访问使用。 MusicG…

Spring AI 第二讲 之 Chat Model API 第八节Anthropic 3 Chat

Anthropic Claude 是一系列基础人工智能模型,可用于各种应用。对于开发人员和企业来说,您可以利用 API 访问,直接在 Anthropic 的人工智能基础架构之上进行构建。 Spring AI 支持用于同步和流式文本生成的 Anthropic 消息 API。 Anthropic …

29网课交单平台 epay.php SQL注入漏洞复现

0x01 产品简介 29网课交单平台是一个专注于在线教育和知识付费领域的交单平台。该平台基于PHP开发,通过全开源修复和优化,为用户提供了高效、稳定、安全的在线学习和交易环境。作为知识付费系统的重要组成部分,充分利用了互联网的优势,为用户提供了便捷的支付方式、高效的…

2.Rust自动生成文件解析

目录 一、生成目录解析二、生成文件解析2.1 Cargo.toml2.2 main函数解析 一、生成目录解析 先使用cargo clean命令删除所有生成的文件,下图显示了目录结构和 main.rs文件 使用cargo new testrust时自动创建出名为testrust的Rust项目。内部主要包含一个src的源码文…