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

news2024/11/19 9:25:36

 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 ngrams

def ngram_frequencies(texts, n=2):
    from collections import Counter
    ngrams_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 FreqDist

def 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 0
    recall_val = tp / (tp + fn) if tp + fn > 0 else 0
    f_measure_val = 2 * precision_val * recall_val / (precision_val + recall_val) if precision_val + recall_val > 0 else 0
    return precision_val, recall_val, f_measure_val

precision_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.coloradmin.cn/o/1799186.html

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

相关文章

106.网络游戏逆向分析与漏洞攻防-装备系统数据分析-在UI中显示装备与技能信息

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 如果看不懂、不知道现在做的什么,那就跟着做完看效果,代码看不懂是正常的,只要会抄就行,抄着抄着就能懂了 内容…

vue3组件传值---vue组件通过属性,事件和provide,inject进行传值

通过属性传值(父传子) vue的组件具有props自建属性(自定义名称,类似于class,id的属性),通过这个属性,父组件可以向子组件传递参数,从而实现组件之间的信息传递&#xff0…

【深度学习】【机器学习】支持向量机,网络入侵检测,KDD数据集

文章目录 环境加载数据归一化数据训练模型用测试数据集给出评估指标准确率召回率预测某个输入数据随便取一行数据加载训练好的SVM支持向量机模型并预测 全部数据和代码下载 环境 之前介绍过用深度学习做入侵检测,这篇用向量机。 环境Python3.10 requirements.txt…

深度解析:短剧市场的发展趋势

一、 短剧视频的兴起 小程序短剧视频是近年来在社交媒体平台上崭露头角的一种内容形式,其独特的表达方式吸引了大量用户的关注,这种类型的视频通常以小幅度、短时长的剧情为主,具有轻松幽默的风格,适合在碎片化的时间作为娱乐消遣…

OpenFeign --学习笔记

什么是OpenFeign? OpenFeign可以想象成一座连接客户端(服务器)和服务器之间的桥梁。在微服务架构中,各个服务之间像小岛屿一样分布在网络上,它们需要相互通信才能协同工作。但是,这些岛屿之间并没有现成的…

el-dialog给弹框标题后加图标,鼠标悬停显示详细内容

效果&#xff1a; 代码&#xff1a; <div slot"title" class"el-dialog__title">标题<el-tooltip effect"dark" placement"right"><div slot"content">鼠标悬停显示</div><i class"el-icon…

AI绘画入门教程(非常详细)从零基础入门到精通,看完这一篇就够了

AI绘画的出现&#xff0c;让越来越多的人可以轻松画出美丽的插画作品。在本篇文章中&#xff0c;我们将会使用AI绘画软件&#xff1a;触站&#xff0c;轻松创建属于自己的作品。从零开始学AI绘画&#xff01; 从零开始学AI绘画关键步骤&#xff1a; 第一步&#xff1a;下载软…

MatrixOne→MatrixOS:矩阵起源的创业史即将用“AI Infra”和“AI Platform”书写新章程

在数字化浪潮的推动下&#xff0c;MatrixOne的故事就像一部科技界的创业史诗&#xff0c;它始于一个简单而宏伟的梦想——构建一个能够支撑起新一代数字世界的操作系统。想象一下&#xff0c;在AIGC时代&#xff0c;数据流动如同“血液”&#xff0c;算法运转如同“心跳”&…

<microros> 如何自定义uROS2数据类型

如何自定义数据类型 在microros中&#xff0c;我们可以看到&#xff0c;官方给我们提供了很多数据类型。 如果我们在实际使用的时候&#xff0c;这些类型无法满足我们的传输要求怎么办呢&#xff1f; 官方也提供了自定义数据类型的办法。 参考&#xff1a; https://github…

深度学习的实用性探究:虚幻还是现实?

深度学习的实用性探究&#xff1a;虚幻还是现实&#xff1f; 深度学习作为人工智能领域的一个热点&#xff0c;已经在学术和工业界引起了广泛的关注。尽管深度学习技术显示出惊人的性能和潜力&#xff0c;但有时它们给人的感觉是“虚”的&#xff0c;或许是因为它们的抽象性和…

MySQL进阶——索引使用规则

在上篇文章我们学习了MySQL进阶——索引&#xff0c;这篇文章学习MySQL进阶——索引使用规则。 索引使用规则 在使用索引时&#xff0c;需要遵守一些使用规则&#xff0c;否则索引会部分失效或全部失效。 最左前缀法则 最左前缀法则是查询从索引的最左列开始&#xff0c;并…

C语言字符、数组指针变量

目录 一、字符指针变量 二、数组指针变量 a.数组指针变量是什么 b.数组指针变量的书写格式 c.数组指针变量如何初始化 d.二维数组传参的本质 一、字符指针变量 在指针的类型中我们知道有一种指针类型为字符指针 char* 。 其一般使用&#xff1a; int main() {char ch w…

解决:Navicat导入sql脚本时报2006

目录 问题复现原因分析解决办法问题小结 1) MySQL 服务宕了 2) mysql连接超时 3) mysql请求链接进程被主动kill 4) Your SQL statement was too large. 问题复现 今天在用Navicat 16.0.6导入.sql文件时&#xff0c;运行一半就报错了。错误如下&#xff1a; [E…

机器学习实验----支持向量机(SVM)实现二分类

目录 一、介绍 (1)解释算法 (2)数据集解释 二、算法实现和代码介绍 1.超平面 2.分类判别模型 3.点到超平面的距离 4.margin 间隔 5.拉格朗日乘数法KKT不等式 (1)介绍 (2)对偶问题 (3)惩罚参数 (4)求解 6.核函数解决非线性问题 7.SMO (1)更新w (2)更新b 三、代…

【机器学习数据挖掘】基于ARIMA 自回归积分滑动平均模型的销售价格库存分析报告 附完整python代码

资源地址&#xff1a;Python数据分析大作业 4000字 图文分析文档 销售分析 完整python代码 ​ 完整代码分析 同时销售量后1000的sku品类占比中&#xff08;不畅销产品&#xff09;如上&#xff0c;精品类产品占比第一&#xff0c;达到66.7%&#xff0c;其次是香化类产品&#…

别人状告你怎么办?你知道还可反告吗?

别人状告你怎么办&#xff1f;你知道还可反告吗&#xff1f; --李秘书讲写作&#xff1a;关于反诉状的写作技巧与策略 反诉状是民事诉讼中的一种重要法律文书&#xff0c;它允许被告在原告提起诉讼后&#xff0c;对原告提起反诉&#xff0c;以抵消原告的诉讼请求。李秘书这节…

视频会议开发:为什么必须使用显卡GPU解码渲染视频?

现在&#xff0c;使用视频会议系统远程协同办公、沟通交流&#xff0c;已经非常普遍了。如果我们要开发自己的视频会议系统&#xff0c;那么&#xff0c;GPU解码渲染技术是不可缺少的。 在视频会议系统中&#xff0c;经常需要同时观看会议中多个参会人员的视频图像&#xff0c;…

Ant Design Pro

一&#xff1a;Ant Design pro是什么&#xff1a; Ant Design Pro 是基于 Ant Design 和 umi 的封装的一整套企业级中后台前端/设计解决方案&#xff0c;致力于在设计规范和基础组件的基础上&#xff0c;继续向上构建&#xff0c;提炼出典型模板/业务组件/配套设计资源&#x…

【js】input设置focus()不生效

实现功能&#xff1a;点击添加文章标签的时候&#xff0c;输入框聚焦。 页面上&#xff0c;input输入框默认不显示&#xff0c;是display:none; 点击添加按钮后&#xff0c;input输入框才显示。 在js里面直接获取元素进行设置聚焦不成功 。 ∵ focus方法比show方法先执行。j…

【MySQL】MySQL Connect -- 详解

一、Connector / C 使用 要使用 C 语言连接 MySQL&#xff0c;需要使用 MySQL 官网提供的库&#xff0c;可以去官网进行下载&#xff1a;MySQL :: MySQL Community Downloads 我们使用 C 接口库来进行连接&#xff0c;要正确使用&#xff0c;还需要做一些准备工作&#xff1a…