fasttext文本分类实战

news2024/11/22 4:30:31

什么是 fastText?

fastText是一个用于高效学习词表示和句子分类的库。

Requirements

fastText可以在现代的Mac OS和Linux发行版上构建。由于它使用了C++11特性,因此需要一个具有良好C++11支持的编译器。这些包括:
(gcc-4.6.3 or newer) or (clang-3.3 or newer)
编译是使用Makefile进行的,所以你需要有一个可用的make。对于词相似度评估脚本,你需要:
python 2.6 or newer
numpy & scipy

Text classification

文本分类是许多应用的核心问题,如垃圾邮件检测、情感分析或智能回复。在本教程中,我们将描述如何使用fastText工具构建一个文本分类器。

1.什么是 text classification?

文本分类的目标是将文档(如电子邮件、帖子、短信、产品评论等)分配到一个或多个类别中。这些类别可以是评论分数、垃圾邮件与非垃圾邮件,或者文档输入的语言。如今,构建此类分类器的占主导地位的方法是机器学习,即从示例中学习分类规则。为了构建这样的分类器,我们需要标记数据,这些数据由文档及其相应的类别(或标签)组成。
例如,我们构建一个分类器,它能够自动将关于烹饪的stackexchange问题分类到几个可能的标签之一,如锅、碗或烘焙。

1. Installing fastText

本教程的第一步是安装和构建fastText。它只需要一个对c++11支持良好的c++编译器。
让我们从下载最新版本开始:

$ wget https://github.com/facebookresearch/fastText/archive/v0.9.2.zip
$ unzip fastText-0.9.2.zip

这里如果下载有问题可以使用我下载好的包,存储在csdn资源中, 这里

移动到fastText目录并构建它

$ cd fastText-0.9.2
# for command line tool :
$ make
make
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/args.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/autotune.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/matrix.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/dictionary.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/loss.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/productquantizer.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/densematrix.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/quantmatrix.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/vector.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/model.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/utils.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/meter.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG -c src/fasttext.cc
c++ -pthread -std=c++11 -march=native -O3 -funroll-loops -DNDEBUG args.o autotune.o matrix.o dictionary.o loss.o productquantizer.o densematrix.o quantmatrix.o vector.o model.o utils.o meter.o fasttext.o src/main.cc -o fasttext
# for python bindings :
$ pip install .
/software_work/fastText-0.9.2
  Preparing metadata (setup.py) ... done
Collecting pybind11>=2.2 (from fasttext==0.9.2)
  Using cached pybind11-2.13.6-py3-none-any.whl.metadata (9.5 kB)
Requirement already satisfied: setuptools>=0.7.0 in /opt/anaconda3/envs/ollama_llamaindex_env/lib/python3.9/site-packages (from fasttext==0.9.2) (75.1.0)
Requirement already satisfied: numpy in /opt/anaconda3/envs/ollama_llamaindex_env/lib/python3.9/site-packages (from fasttext==0.9.2) (1.26.4)
Using cached pybind11-2.13.6-py3-none-any.whl (243 kB)
Building wheels for collected packages: fasttext
  Building wheel for fasttext (setup.py) ... done
  Created wheel for fasttext: filename=fasttext-0.9.2-cp39-cp39-macosx_14_0_arm64.whl size=282107 sha256=1f534a1137278a8c3c1d4462625b32774e68774d9d1b3738c59187c6ad06ed79
  Stored in directory: /Library/Caches/pip/wheels/c0/08/8d/0ba724ecdf97554e67d943ab13b3071f21b620a027bcaace75
Successfully built fasttext
Installing collected packages: pybind11, fasttext
Successfully installed fasttext-0.9.2 pybind11-2.13.6

调用帮助函数将显示库的高级文档:

>>> import fasttext
>>> help(fasttext.FastText)
在fasttext模块中对fasttext.FastText的帮助:

NAME
    fasttext.FastText

DESCRIPTION
    # Copyright (c) 2017-present, Facebook, Inc.
    # All rights reserved.
    #
    # This source code is licensed under the MIT license found in the
    # LICENSE file in the root directory of this source tree.

FUNCTIONS
    load_model(path)
        加载给定文件路径的模型,并返回一个模型对象。

    read_args(arg_list, arg_dict, arg_names, default_values)

    tokenize(text)
        给定一段文本字符串,对其进行分词并返回一个令牌列表。

    train_supervised(*kargs, **kwargs)
        训练一个监督模型并返回一个模型对象。

        输入必须是文件路径。输入文本不需要按照tokenize函数进行分词,但它必须经过预处理并编码为UTF-8。你可能需要参考标准的预处理脚本,例如在这里提到的tokenizer.perl:http://www.statmt.org/wmt07/baseline.html

        输入文件必须每行至少包含一个标签。例如,可以参考fastText仓库中的一部分示例数据集,例如由classification-example.sh脚本获取的数据集。

    train_unsupervised(*kargs, **kwargs)
        训练一个无监督模型并返回一个模型对象。

        输入必须是文件路径。输入文本不需要按照tokenize函数进行分词,但它必须经过预处理并编码为UTF-8。你可能需要参考标准的预处理脚本,例如在这里提到的tokenizer.perl:http://www.statmt.org/wmt07/baseline.html

        输入字段不得包含任何标签或使用指定的标签前缀,除非那些词被忽略是可以接受的。例如,可以参考fastText仓库中的一部分示例脚本word-vector-example.sh获取的数据集。

在本教程中,我们主要使用train_supervised函数,它返回一个模型对象,并在这个对象上调用test和predict方法。这对应于学习(和使用)文本分类器。要了解fastText的其他功能,请参阅关于学习词向量的教程。

2.获取和准备数据

如引言中所述,我们需要标记数据来训练我们的监督分类器。在本教程中,我们感兴趣的是构建一个分类器,自动识别关于烹饪的Stackexchange问题的主题。让我们从Stackexchange的烹饪部分下载问题示例及其相关的标签:

>> wget https://dl.fbaipublicfiles.com/fasttext/data/cooking.stackexchange.tar.gz && tar xvzf cooking.stackexchange.tar.gz
>> head cooking.stackexchange.txt
__label__sauce __label__cheese How much does potato starch affect a cheese sauce recipe?
__label__food-safety __label__acidity Dangerous pathogens capable of growing in acidic environments
__label__cast-iron __label__stove How do I cover up the white spots on my cast iron stove?
__label__restaurant Michelin Three Star Restaurant; but if the chef is not there
__label__knife-skills __label__dicing Without knife skills, how can I quickly and accurately dice vegetables?
__label__storage-method __label__equipment __label__bread What's the purpose of a bread box?
__label__baking __label__food-safety __label__substitutions __label__peanuts how to seperate peanut oil from roasted peanuts at home?
__label__chocolate American equivalent for British chocolate terms
__label__baking __label__oven __label__convection Fan bake vs bake
__label__sauce __label__storage-lifetime __label__acidity __label__mayonnaise Regulation and balancing of readymade packed mayonnaise and other sauces

文本文件的每一行都包含一个标签列表,后跟相应的文档。所有标签都以__label__前缀开头,这就是fastText识别什么是标签什么是单词的方式。然后,模型被训练来预测给定文档中的单词的标签。

在训练我们的第一个分类器之前,我们需要将数据分为训练集和验证集。我们将使用验证集来评估学习到的分类器在新的数据上的表现如何。

wc cooking.stackexchange.txt
15404  169582 1401900 cooking.stackexchange.txt

我们的完整数据集包含15404个示例。让我们将其分为一个包含12404个示例的训练集和一个包含3000个示例的验证集:

>> head -n 12404 cooking.stackexchange.txt > cooking.train
>> tail -n 3000 cooking.stackexchange.txt > cooking.valid
3.训练一个分类器
import fasttext
model = fasttext.train_supervised(input="cooking.train")
Read 0M words
Number of words:  14598
Number of labels: 734
Progress: 100.0%  words/sec/thread: 75109  lr: 0.000000  loss: 10.708354  eta: 0h0m

输入参数指示包含训练示例的文件。我们现在可以使用模型变量来访问有关训练模型的信息。我们还可以调用save_model将其保存为文件,并稍后使用load_model函数加载它。

model.save_model("model_cooking.bin")

现在我们可以测试一下训练好的分类器

model.predict("Which baking dish is best to bake a banana bread ?")
((u'__label__baking',), array([0.15613931]))

预测的标签是baking,这与这个问题非常吻合。现在让我们尝试第二个例子:

model.predict("Why not put knives in the dishwasher?")
((u'__label__food-safety',), array([0.08686075]))

模型预测的标签是food-safety,这与问题不相关。在某种程度上,模型似乎在简单示例上失败了。
为了更好地了解其质量,让我们在验证数据上测试它,运行:

model.test("cooking.valid")
(3000L, 0.124, 0.0541)

输出是样本数量(这里3000),精确度为1(0.124)和召回率为1(0.0541)。
我们还可以计算精确度为5和召回率为5,使用:

model.test("cooking.valid", k=5)
(3000L, 0.0668, 0.146)

延伸阅读: precision and recall

精确度是指fastText预测的标签中正确标签的数量。召回率是指成功预测的标签中,所有真实标签的数量。让我们举一个例子来更清楚地说明这一点:
Why not put knives in the dishwasher?
在Stack Exchange上,这个句子被标记了三个标签:equipment, cleaning 和 knives。模型预测的前五个标签可以通过以下方式获得:

model.predict("Why not put knives in the dishwasher?", k=5)
((u'__label__food-safety', u'__label__baking', u'__label__equipment', u'__label__substitutions', u'__label__bread'), array([0.0857 , 0.0657, 0.0454, 0.0333, 0.0333]))

预测的五个标签中,有一个是正确的,即equipment,这给出了0.20的精确度。在三个真实标签中,只有一个被模型预测,即设备,这给出了0.33的召回率。
更多详情,请参阅相关的维基百科页面。

4. 提高模型的准确率

通过使用默认参数运行fastText获得的模型在分类新问题方面表现相当差。让我们尝试通过更改默认参数来提高性能。

数据准备
观察数据,我们发现有些单词包含大写字母或标点符号。提高我们模型性能的第一步是应用一些简单的预处理。可以使用命令行工具(如sed和tr)来获得粗略的规范化:

>> cat cooking.stackexchange.txt | sed -e "s/\([.\!?,'/()]\)/ \1 /g" | tr "[:upper:]" "[:lower:]" > cooking.preprocessed.txt
>> head -n 12404 cooking.preprocessed.txt > cooking.train
>> tail -n 3000 cooking.preprocessed.txt > cooking.valid
5. 使用预处理的数据重新训练模型
model = fasttext.train_supervised(input="cooking.train")
Read 0M words
Number of words:  9012
Number of labels: 734
Progress: 100.0%  words/sec/thread: 82041  lr: 0.000000  loss: 5.671649  eta: 0h0m

>>> model.test("cooking.valid")
(3000L, 0.164, 0.0717)

我们观察到,由于预处理,词汇量变小了(从14k个单词减少到9k个)。精确度也提高了4%!

6. 更多的周期和更大的学习率

默认情况下,fastText在训练期间只看到每个训练示例五次,这对于我们只有12k训练示例的训练集来说是非常小的。每个示例被看到的次数(也称为周期数)可以使用-epoch选项增加:

import fasttext
model = fasttext.train_supervised(input="cooking.train", epoch=25)
Read 0M words
Number of words:  9012
Number of labels: 734
Progress: 100.0%  words/sec/thread: 77633  lr: 0.000000  loss: 7.147976  eta: 0h0m

然后测试一下新的模型

>>> model.test("cooking.valid")
(3000L, 0.501, 0.218)

这好多了!另一种改变我们模型学习速度的方法是增加(或减少)算法的学习率。这对应于模型在处理每个示例后变化的程度。学习率为0意味着模型根本不变化,因此,它不会学习任何东西。学习率的良好值在0.1 - 1.0的范围内。

model = fasttext.train_supervised(input="cooking.train", lr=1.0, epoch=25)
Read 0M words
Number of words:  9012
Number of labels: 734
Progress: 100.0%  words/sec/thread: 76394  lr: 0.000000  loss: 4.350277  eta: 0h0m

>>> model.test("cooking.valid")
(3000L, 0.585, 0.255)

现在,让我们添加更多的功能来进一步提高我们的性能!

最后,我们可以通过使用词二元语法(bigrams)而不是仅使用词元(unigrams)来提高模型的性能。这对于词序重要的分类问题尤为重要,例如情感分析。

model = fasttext.train_supervised(input="cooking.train", lr=1.0, epoch=25, wordNgrams=2)
Read 0M words
Number of words:  9012
Number of labels: 734
Progress: 100.0%  words/sec/thread: 75366  lr: 0.000000  loss: 3.226064  eta: 0h0m

model.test("cooking.valid")
(3000L, 0.599, 0.261)

通过几个步骤,我们能够将精确度从12.4%提高到59.9%。重要的步骤包括:
预处理数据;
更改周期数(使用选项-epoch,标准范围[5 - 50]);
更改学习率(使用选项-lr,标准范围[0.1 - 1.0]);
使用词n-gram(使用选项-wordNgrams,标准范围[1 - 5])。

2. 延伸阅读: 什么是Bigram?

'unigram’指的是单个不可分割的单位或令牌,通常作为模型的输入。例如,unigram可以是单词或字母,取决于模型。在fastText中,我们工作在单词级别,因此unigrams是单词。
类似地,我们用’bigram’表示两个连续令牌或单词的拼接。类似地,我们经常谈论n-gram来指代任何n个连续令牌的拼接。

例如,在句子“Last donut of the night”中,unigrams 是 ‘last’, ‘donut’, ‘of’, ‘the’ 和 ‘night’。Bigrams 包括 ‘Last donut’, ‘donut of’, ‘of the’ 和 ‘the night’。
Bigrams 特别有趣,因为对于大多数句子,你可以仅通过查看 n-gram 的集合来重构单词的顺序。
让我们通过一个简单的练习来说明这一点,给出以下 bigrams,尝试重构原始句子:‘all out’, ‘I am’, ‘of bubblegum’, ‘out of’ 和 ‘am all’。通常将一个单词称为 unigram。

扩大规模
既然我们的模型只在上千个示例上进行训练,训练过程只需几秒钟。但是,在更大的数据集上,带有更多标签的训练可能会开始变得缓慢。为了加快训练速度,一个潜在的解决方案是使用层次softmax,而不是常规的softmax。这可以通过选项 -loss hs: 来实现。

model = fasttext.train_supervised(input="cooking.train", lr=1.0, epoch=25, wordNgrams=2, bucket=200000, dim=50, loss='hs')
Read 0M words
Number of words:  9012
Number of labels: 734
Progress: 100.0%  words/sec/thread: 2199406  lr: 0.000000  loss: 1.718807  eta: 0h0m

现在训练应该不到一秒钟。

3. 扩展阅读: hierarchical softmax

层次softmax是一种损失函数,它通过更快的计算来近似softmax。
这个想法是构建一个二叉树,其叶子节点对应于标签。每个中间节点都有一个二元决策激活(例如,sigmoid),它是可训练的,并预测我们是应该向左还是向右走。输出单元的概率然后由从根到输出单元叶子的路径上中间节点的概率的乘积给出。

如果您想要更详细的解释,可以观看这个视频。
在fastText中,我们使用霍夫曼树,这样对于更频繁的输出,查找时间更快,因此输出的平均查找时间是最优的。

4. 多标签分类

当我们想要将一个文档分配给多个标签时,我们仍然可以使用softmax损失,并调整预测参数,即要预测的标签数量和预测概率的阈值。然而,调整这些参数可能会很棘手且不直观,因为概率之和必须等于1。

处理多个标签的一种方便方法是使用独立的二元分类器对每个标签进行分类。这可以通过使用 -loss one-vs-all 或 -loss ova 来实现。

model = fasttext.train_supervised(input="cooking.train", lr=0.5, epoch=25, wordNgrams=2, bucket=200000, dim=50, loss='ova')
Read 0M words
Number of words:  14543
Number of labels: 735
Progress: 100.0% words/sec/thread:   72104 lr:  0.000000 loss:  4.340807 ETA:   0h 0m

与其他损失函数相比,降低学习率是一个好主意。
现在让我们来看看我们的预测,我们希望尽可能多的预测(参数 -1),并且我们只想要概率高于或等于0.5的标签:

model.predict("Which baking dish is best to bake a banana bread ?", k=-1, threshold=0.5)
((u''__label__baking, u'__label__bananas', u'__label__bread'), array([1.00000, 0.939923, 0.592677]))

我们还可以使用测试函数来评估我们的结果。

model.test("cooking.valid", k=-1)
(3000L, 0.702, 0.2)

总结

在本教程中,我们简要介绍了如何使用fastText来训练强大的文本分类器。我们简要回顾了一些最重要的调优选项。

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

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

相关文章

[ 网络安全介绍 1 ] 什么是网络安全?

🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…

R语言4.3.0安装教程【附安装包】

R for Windows是一个免费的用于统计计算和统计制图的优秀工具,是R语言开发工具。它拥有数据存储和处理系统、数组运算工具(其向量、矩阵运算方面功能尤其强大)、完整连贯的统计分析工具、优秀的统计制图等功能。提供的图形界面,可…

【网络】Socket编程TCP/UDP序列化和反序列化理解应用层(C++实现)Json::Value

主页:醋溜马桶圈-CSDN博客 专栏:计算机网络原理_醋溜马桶圈的博客-CSDN博客 gitee:mnxcc (mnxcc) - Gitee.com 目录 1.基于Socket的UDP和TCP编程介绍 1.1 基本TCP客户—服务器程序设计基本框架 ​编辑1.2 基本UDP客户—服务器程序设计基本框…

小熊派Nano接入华为云

一、华为云IoTDA创建产品 创建如下服务,并添加对应的属性和命令。 二、小熊派接入 根据小熊派官方示例代码D6完成了小熊派接入华为云并实现属性上传命令下发。源码:小熊派开源社区/BearPi-HM_Nano 1. MQTT连接代码分析 这部分代码在oc_mqtt.c和oc_mq…

如何在 Ubuntu 上安装 Jellyfin 媒体服务器

Jellyfin 是一个开源的媒体服务器软件,让你可以整理、管理和流式传输你的个人媒体收藏,比如电影、音乐、电视节目和照片,而且完全免费,没有订阅费用或数据收集的担忧。 简介 媒体管理:Jellyfin 整理媒体库&#xff0…

Android集成FCM(Firebace Cloud Messaging )

集成FCM官方文档 Firebace主页面 将 Firebase 添加到您的 Android 应用 1、进入Firebace页面,创建自己的项目 2、点击自己创建好的项目,在右侧选择Cloud Messaging 3、点击Android去创建 google-services.json 4、将下载的 google-services.json 文件…

实时直播平台如何实现美颜功能?第三方美颜API与美颜SDK的技术

通过实时美颜技术,主播可以轻松实现肤色优化、五官调整以及滤镜效果,极大提升观众的观看体验。本篇文章,小编将深入讲解实时直播平台如何通过第三方美颜API与美颜SDK实现美颜功能,以及其中的技术实现与关键要点。 一、实时美颜的…

使用GDB或Delve对已经运行起来的Go程序进行远程调试

同步发布在我的博客,欢迎来点赞。 使用 GDB 或 Delve 对已经运行起来的 Go 程序进行远程调试 使用 GDB 或 Delve 对已经运行起来的 Go 程序进行远程调试 背景 Java 程序可以很方便地通过 jdwp 参数指定一个对外端口进行远程调试,如 java \ -agentlib…

Ubuntu问题 -- 设置ubuntu的IP为静态IP (图形化界面设置) 小白友好

目的 为了将ubuntu服务器IP固定, 方便ssh连接人在服务器前使用图形化界面设置 设置 找到自己的网卡名称, 我的是 eno1, 并进入设置界面 查看当前的IP, 网关, 掩码和DNS (注意对应eno1) nmcli dev show掩码可以通过以下命令查看完整的 (注意对应eno1) , 我这里是255.255.255.…

实现一个string的indexof方法,给出时空复杂度估计

文心快码(BaiduComate)是基于百度文心大模型,在研发全流程全场景下为开发者提供辅助建议的智能代码助手。结合百度积累多年的编程现场大数据、外部优秀开源数据,可为开发者生成更符合实际研发场景的优秀代码,提升编码效率,释放“十…

ESP8266 STA模式TCP客户端 电脑手机网络调试助手

1.STA模式TCP客户端和电脑网络调试助手 2.STA模式TCP客户端和手机网络调试助手

【lamafactory BLEU ROUGLE L评测】

1、BLEU/ROUGLE评测界面 2、这个是用BLEU 和ROUGL来评测 目录:saves/Qwen2-7B-Chat/lora/eval_2024-11-14-16-28-19/ 在saves文件夹 生成的文件如下 all_results.json文件 说明模型在这个测试集上是不好的 3、可以查看预测结果的文件 predict_result.json

Ros Noetic 20.04 跑通mpc_ros包保姆级教程

前言: 本文将简述mpc_ros包在noetic20.04中的安装,mpc是 一种跟踪、MPC_ROS 是一个基于ROS(Robot Operating System)的模型预测控制(Model Predictive Control,MPC)库。该项目旨在为机器人控制提供一个灵活且高效的MPC实现,使得开发者能够在ROS环境中轻松集成和使用MPC…

游戏+AI的发展历程,AI技术在游戏行业的应用有哪些?

人工智能(AI)与游戏的结合,不仅是技术进步的体现,更是人类智慧的延伸。从最初的简单规则到如今的复杂决策系统,AI在游戏领域的发展历史可谓波澜壮阔。 早在2001年,就有研究指出游戏人工智能领域&#xff0…

HarmonyOs DevEco Studio小技巧31--卡片的生命周期与卡片的开发

Form Kit简介 Form Kit(卡片开发服务)提供一种界面展示形式,可以将应用的重要信息或操作前置到服务卡片(以下简称“卡片”),以达到服务直达、减少跳转层级的体验效果。卡片常用于嵌入到其他应用&#xff0…

Redis的过期删除策略和内存淘汰机制以及如何保证双写的一致性

Redis的过期删除策略和内存淘汰机制以及如何保证双写的一致性 过期删除策略内存淘汰机制怎么保证redis双写的一致性?更新策略先删除缓存后更新数据库先更新数据库后删除缓存如何选择?如何保证先更新数据库后删除缓存的线程安全问题? 过期删除策略 为了…

单元测试框架gtest学习(三)—— 事件机制

前言 上节我们学习了gtest的各种宏断言 单元测试框架gtest学习(二)—— 认识断言-CSDN博客 本节我们介绍gtets的事件机制 虽然 Google Test 的核心是用来编写单元测试和断言的,但它也允许在测试执行过程中进行事件的钩取和自定义&#xf…

Unity Inspector窗口可编辑的脚本变量

Inspector可编辑的脚本变量 默认会显示的变量 在Unity中,为了方便我们进行一些属性的设置及调试,我们所写的公有基础数据类型会显示在Inspector之中,我们可以对他进行设置来更改它的取值。 显示私有变量 在有些情况下,设计代码…

力扣 LeetCode 110. 平衡二叉树(Day8:二叉树)

解题思路: 等于 -1 时,直接 return -1 class Solution {public boolean isBalanced(TreeNode root) {return getHeight(root) ! -1;}public int getHeight(TreeNode root) {if (root null) return 0;int leftDepth getHeight(root.left);if (leftDep…

unity3d————基础篇小项目(设置界面)

代码示例&#xff1a; 设置界面 using System.Collections; using System.Collections.Generic; using UnityEngine;public class SettingPanel : BasePanel<SettingPanel> {public UIButton btnClose;public UISlider sliderMusic;public UISlider sliderSound;public…