工具系列:PyCaret介绍_Fugue 集成_Spark、Dask分布式训练

news2025/4/6 13:49:18

工具系列:PyCaret介绍_Fugue 集成_Spark、Dask分布式训练

Fugue 是一个低代码的统一接口,用于不同的计算框架,如 Spark、Dask。PyCaret 使用 Fugue 来支持分布式计算场景。

目录

1、分布式计算示例:

(1)分类

(2)回归

(3)时间序列

2、应用技巧

(1)在设置中使用lambda而不是dataframe

(2)保持确定性

(3)设置n_jobs

(4)设置适当的批量大小

(5)显示进度

(6)自定义指标

(7)Spark设置

(8)Dask设置

(9)本地并行化

(10)如何开发

1、分布式计算场景

(1)分类

让我们从最标准的例子开始,代码与本地版本完全相同,没有任何魔法。

# 导入所需的库
from pycaret.datasets import get_data  # 导入获取数据的函数
from pycaret.classification import *  # 导入分类模型

# 使用get_data函数获取名为"juice"的数据集,并设置verbose参数为False,表示不显示详细信息
data = get_data("juice", verbose=False)

# 设置目标变量为'Purchase',n_jobs参数为1表示使用单个进程
setup(data=data, target='Purchase', n_jobs=1)

# 获取前5个模型的名称,并存储在test_models变量中
test_models = models().index.tolist()[:5]

在这里插入图片描述

compare_model如果您不想使用分布式系统,也完全相同。

# 比较模型函数
compare_models(include=test_models, n_select=2)

在这里插入图片描述

Processing:   0%|          | 0/26 [00:00<?, ?it/s]





[LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                    intercept_scaling=1, l1_ratio=None, max_iter=1000,
                    multi_class='auto', n_jobs=None, penalty='l2',
                    random_state=4292, solver='lbfgs', tol=0.0001, verbose=0,
                    warm_start=False),
 DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',
                        max_depth=None, max_features=None, max_leaf_nodes=None,
                        min_impurity_decrease=0.0, min_samples_leaf=1,
                        min_samples_split=2, min_weight_fraction_leaf=0.0,
                        random_state=4292, splitter='best')]

现在让我们将其分布式,作为一个玩具案例,在dask上。唯一改变的是一个额外的参数parallel_backend

# 导入所需的库
from pycaret.parallel import FugueBackend

# 使用FugueBackend作为并行计算的后端

# compare_models函数用于比较多个模型的性能
# include参数指定要比较的模型列表
# n_select参数指定要选择的最佳模型数量
# parallel参数指定使用的并行计算后端,这里使用FugueBackend("dask")表示使用Dask作为并行计算后端

compare_models(include=test_models, n_select=2, parallel=FugueBackend("dask"))

在这里插入图片描述

[LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                    intercept_scaling=1, l1_ratio=None, max_iter=1000,
                    multi_class='auto', n_jobs=None, penalty='l2',
                    random_state=4292, solver='lbfgs', tol=0.0001, verbose=0,
                    warm_start=False),
 DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',
                        max_depth=None, max_features=None, max_leaf_nodes=None,
                        min_impurity_decrease=0.0, min_samples_leaf=1,
                        min_samples_split=2, min_weight_fraction_leaf=0.0,
                        random_state=4292, splitter='best')]

为了使用Spark作为执行引擎,您必须能够访问一个Spark集群,并且必须拥有一个SparkSession,让我们初始化一个本地的Spark会话。

# 导入SparkSession模块
from pyspark.sql import SparkSession

# 创建或获取SparkSession对象
spark = SparkSession.builder.getOrCreate()

现在只需将parallel_backend更改为此会话对象,即可在Spark上运行。您必须明白这只是一个玩具案例。在实际情况中,您需要拥有一个指向真实Spark集群的SparkSession,才能享受Spark的强大功能。

# 调用 compare_models 函数,传入参数 include=test_models、n_select=2 和 parallel=FugueBackend(spark)
compare_models(include=test_models, n_select=2, parallel=FugueBackend(spark))

在这里插入图片描述

[LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                    intercept_scaling=1, l1_ratio=None, max_iter=1000,
                    multi_class='auto', n_jobs=None, penalty='l2',
                    random_state=4292, solver='lbfgs', tol=0.0001, verbose=0,
                    warm_start=False),
 DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',
                        max_depth=None, max_features=None, max_leaf_nodes=None,
                        min_impurity_decrease=0.0, min_samples_leaf=1,
                        min_samples_split=2, min_weight_fraction_leaf=0.0,
                        random_state=4292, splitter='best')]

最后,你可以使用pull命令来获取指标表格。

pull()

在这里插入图片描述

(2)回归

回归问题与分类问题遵循相同的模式。

# 导入所需的库
from pycaret.datasets import get_data  # 导入获取数据的函数
from pycaret.regression import *  # 导入回归模型

# 设置数据和目标变量
setup(data=get_data("insurance", verbose=False), target='charges', n_jobs=1)

# 获取前5个模型
test_models = models().index.tolist()[:5]

在这里插入图片描述

compare_model如果您不想使用分布式系统,也完全相同。

# 比较模型性能的函数
# 参数:
# include: 需要比较的模型列表
# n_select: 需要选择的模型数量
# sort: 按照哪个指标进行排序,默认为平均绝对误差(MAE)

compare_models(include=test_models, n_select=2, sort="MAE")

在这里插入图片描述

Processing:   0%|          | 0/26 [00:00<?, ?it/s]





[Lars(copy_X=True, eps=2.220446049250313e-16, fit_intercept=True, fit_path=True,
      jitter=None, n_nonzero_coefs=500, normalize='deprecated',
      precompute='auto', random_state=3514, verbose=False),
 LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1,
                  normalize='deprecated', positive=False)]

现在让我们将其分布式,作为一个玩具案例,在dask上。唯一改变的是一个额外的参数parallel_backend

# 导入所需的库
from pycaret.parallel import FugueBackend

# 使用FugueBackend作为并行计算的后端

# compare_models函数用于比较多个模型的性能,并选择性能最好的几个模型
# include参数指定要比较的模型列表
# n_select参数指定要选择的模型数量
# sort参数指定按照哪个指标进行排序,这里选择按照平均绝对误差(MAE)进行排序
# parallel参数指定使用的并行计算后端,这里选择使用FugueBackend("dask")作为并行计算的后端
compare_models(include=test_models, n_select=2, sort="MAE", parallel=FugueBackend("dask"))

在这里插入图片描述

[Lars(copy_X=True, eps=2.220446049250313e-16, fit_intercept=True, fit_path=True,
      jitter=None, n_nonzero_coefs=500, normalize='deprecated',
      precompute='auto', random_state=3514, verbose=False),
 LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1,
                  normalize='deprecated', positive=False)]

为了使用Spark作为执行引擎,您必须能够访问一个Spark集群,并且必须拥有一个SparkSession,让我们初始化一个本地的Spark会话。

# 导入SparkSession模块
from pyspark.sql import SparkSession

# 创建或获取一个SparkSession对象
spark = SparkSession.builder.getOrCreate()

现在只需将parallel_backend更改为此会话对象,即可在Spark上运行。您必须明白这只是一个玩具案例。在真实情况下,您需要拥有一个指向真实Spark集群的SparkSession,才能享受Spark的强大功能。

# 调用compare_models函数,传入参数include=test_models、n_select=2、sort="MAE"和parallel=FugueBackend(spark)
compare_models(include=test_models, n_select=2, sort="MAE", parallel=FugueBackend(spark))

在这里插入图片描述

[Lars(copy_X=True, eps=2.220446049250313e-16, fit_intercept=True, fit_path=True,
      jitter=None, n_nonzero_coefs=500, normalize='deprecated',
      precompute='auto', random_state=3514, verbose=False),
 LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1,
                  normalize='deprecated', positive=False)]

最后,你可以使用pull命令来获取指标表格。

pull()

在这里插入图片描述

(3)时间序列

它遵循与分类相同的模式。

# 导入所需的库和模块
from pycaret.datasets import get_data  # 导入获取数据的函数
from pycaret.time_series import *  # 导入时间序列模块

# 创建时间序列预测实验对象
exp = TSForecastingExperiment()

# 设置实验参数
exp.setup(
    data=get_data('airline', verbose=False),  # 获取数据集,此处使用航空数据集
    fh=12,  # 设置预测的未来时间步数为12
    fold=3,  # 设置交叉验证的折数为3
    fig_kwargs={'renderer': 'notebook'},  # 设置绘图参数,此处使用notebook作为渲染器
    session_id=42  # 设置随机种子为42,保证实验的可重复性
)

# 获取前5个模型的名称
test_models = exp.models().index.tolist()[:5]

在这里插入图片描述

# 比较模型性能并选择最佳模型

# 使用exp.compare_models函数比较模型性能,并选择最佳的3个模型作为基准模型
# 参数include=test_models表示只比较test_models中的模型
# 参数n_select=3表示选择性能最好的3个模型作为最佳基准模型
best_baseline_models = exp.compare_models(include=test_models, n_select=3)
best_baseline_models

在这里插入图片描述

Processing:   0%|          | 0/27 [00:00<?, ?it/s]





[ARIMA(maxiter=50, method='lbfgs', order=(1, 0, 0), out_of_sample_size=0,
       scoring='mse', scoring_args=None, seasonal_order=(0, 1, 0, 12),
       start_params=None, suppress_warnings=False, trend=None,
       with_intercept=True),
 NaiveForecaster(sp=12, strategy='last', window_length=None),
 PolynomialTrendForecaster(degree=1, regressor=None, with_intercept=True)]
# 导入所需的模块
from pycaret.parallel import FugueBackend

# 使用FugueBackend作为并行计算的后端
# FugueBackend是一个用于分布式计算的后端,可以使用Dask或Ray来实现并行计算
# 这里使用了"Dask"作为FugueBackend的参数,表示使用Dask来进行并行计算

# 使用exp.compare_models函数比较模型性能,并选择最佳的3个模型
# include参数指定要比较的模型列表,test_models是一个包含待比较模型的列表
# n_select参数指定要选择的最佳模型的数量,这里选择了3个最佳模型
# parallel参数指定并行计算的后端,这里使用了之前创建的FugueBackend对象

# 将比较结果保存在best_baseline_models变量中,该变量将包含最佳的3个模型
best_baseline_models = exp.compare_models(include=test_models, n_select=3, parallel=FugueBackend("dask"))
best_baseline_models

在这里插入图片描述

[ARIMA(maxiter=50, method='lbfgs', order=(1, 0, 0), out_of_sample_size=0,
       scoring='mse', scoring_args=None, seasonal_order=(0, 1, 0, 12),
       start_params=None, suppress_warnings=False, trend=None,
       with_intercept=True),
 NaiveForecaster(sp=12, strategy='last', window_length=None),
 PolynomialTrendForecaster(degree=1, regressor=None, with_intercept=True)]
# 导入SparkSession模块
from pyspark.sql import SparkSession

# 创建或获取SparkSession对象
spark = SparkSession.builder.getOrCreate()
# 导入所需的模块
from pycaret.parallel import FugueBackend

# 使用FugueBackend作为并行计算的后端

# 使用exp.compare_models函数来比较模型性能并选择最佳模型
# include参数指定要比较的模型列表,这里选择了test_models列表的前两个模型
# n_select参数指定要选择的最佳模型数量,这里选择了3个最佳模型
# parallel参数指定并行计算的后端,这里使用了FugueBackend(spark)

# 将比较结果保存在best_baseline_models变量中
best_baseline_models = exp.compare_models(include=test_models[:2], n_select=3, parallel=FugueBackend(spark))
best_baseline_models

在这里插入图片描述

[NaiveForecaster(sp=1, strategy='last', window_length=None),
 NaiveForecaster(sp=1, strategy='mean', window_length=None)]
# 从exp对象中调用pull()方法
exp.pull()

在这里插入图片描述

2、分布式应用技巧

(1)一个更实际的案例

上面的例子都是纯粹的玩具,为了在分布式系统中使事情完美运行,你必须注意一些事情

(2) 在设置中使用lambda而不是dataframe

如果你直接在setup中提供一个dataframe,这个数据集将需要发送到所有的工作节点。如果dataframe是1G,你有100个工作节点,那么你的驱动机器可能需要发送高达100G的数据(取决于具体框架的实现),这个数据传输本身就成为了一个瓶颈。相反,如果你提供一个lambda函数,它不会改变本地计算的情况,但驱动程序只会将函数引用发送给工作节点,每个工作节点将负责自己加载数据,因此驱动程序端没有大量的流量。

(3) 保持确定性

你应该始终使用session_id来使分布式计算具有确定性。

(4) 设置n_jobs

在想要分布式运行某些任务时,明确设置n_jobs非常重要,这样它就不会过度使用本地/远程资源。这也可以避免资源争用,并加快计算速度。

# 导入所需的库
from pycaret.datasets import get_data  # 导入获取数据的函数
from pycaret.classification import *  # 导入分类模块

# 设置函数,用于获取数据
# 使用get_data函数获取名为"juice"的数据集,关闭冗长输出(verbose=False),关闭数据集的概要信息(profile=False)
# 设置目标变量为'Purchase'
# 设置会话ID为0,以确保结果的可重复性
# 设置使用的CPU核心数为1
setup(data_func=lambda: get_data("juice", verbose=False, profile=False), target='Purchase', session_id=0, n_jobs=1);

在这里插入图片描述

(4)设置适当的批量大小

batch_size参数有助于在负载均衡和开销之间进行调整。对于每个批次,设置将只调用一次。所以

选择负载均衡开销最佳情况
较小的批量大小更好更差训练时间 >> 数据加载时间 或者 模型数量 ~= 工作进程数量
较大的批量大小更差更好训练时间 << 数据加载时间 或者 模型数量 >> 工作进程数量

默认值设置为1,表示我们希望获得最佳的负载均衡。

(5) 显示进度

在开发中,您可以通过display_remote=True启用可视效果,但同时您还必须启用Fugue回调,以便驱动程序可以监视工作进度。但建议在生产环境中关闭显示。

# 导入所需的模块
from pycaret.parallel import FugueBackend

# 定义配置参数
fconf = {
    "fugue.rpc.server": "fugue.rpc.flask.FlaskRPCServer",  # 保持该值不变
    "fugue.rpc.flask_server.host": "0.0.0.0",  # 驱动程序的 IP 地址,工作节点可以访问
    "fugue.rpc.flask_server.port": "3333",  # 驱动程序上的开放端口
    "fugue.rpc.flask_server.timeout": "2 sec",  # 工作节点与驱动程序通信的超时时间
}

# 创建 FugueBackend 对象
be = FugueBackend("dask", fconf, display_remote=True, batch_size=3, top_only=False)

# 使用 FugueBackend 对象进行模型比较
compare_models(n_select=2, parallel=be)

在这里插入图片描述

Processing:   0%|          | 0/14 [00:00<?, ?it/s]















[RidgeClassifier(alpha=1.0, class_weight=None, copy_X=True, fit_intercept=True,
                 max_iter=None, normalize='deprecated', positive=False,
                 random_state=0, solver='auto', tol=0.001),
 LinearDiscriminantAnalysis(covariance_estimator=None, n_components=None,
                            priors=None, shrinkage=None, solver='svd',
                            store_covariance=False, tol=0.0001)]

(6)自定义指标

您可以像以前一样添加自定义指标。但是为了使评分器可分发,它必须是可序列化的。一个常见的函数应该没问题,但是如果在函数内部使用了一些不可序列化的全局变量(例如一个RLock对象),可能会引发问题。因此,请尽量使自定义函数独立于全局变量。

# 定义一个名为score_dummy的函数,用于计算模型的得分
# 参数y_true表示真实值,y_pred表示预测值,axis表示计算得分的轴
def score_dummy(y_true, y_pred, axis=0):
    return 0.0

# 添加一个名为'mydummy'的指标
# 参数id表示指标的唯一标识符
# 参数name表示指标的名称
# 参数score_func表示计算指标得分的函数,这里使用之前定义的score_dummy函数
# 参数target表示指标的计算目标,这里是预测值
# 参数greater_is_better表示得分是否越大越好,这里设置为False,表示得分越小越好
add_metric(id='mydummy',
           name='DUMMY',
           score_func=score_dummy,
           target='pred',
           greater_is_better=False)
Name                                                             DUMMY
Display Name                                                     DUMMY
Score Function                <function score_dummy at 0x7f8aa0dc0ca0>
Scorer               make_scorer(score_dummy, greater_is_better=False)
Target                                                            pred
Args                                                                {}
Greater is Better                                                False
Multiclass                                                        True
Custom                                                            True
Name: mydummy, dtype: object

在类实例中添加一个函数也是可以的,但是请确保类中的所有成员变量都是可序列化的。

# 获取模型列表的前5个模型
test_models = models().index.tolist()[:5]

# 比较模型
# include参数指定要比较的模型列表
# n_select参数指定要选择的模型数量
# sort参数指定排序方式,这里使用"DUMMY"表示不进行排序
# parallel参数指定使用的并行计算后端,这里使用Dask作为后端
compare_models(include=test_models, n_select=2, sort="DUMMY", parallel=FugueBackend("dask"))

在这里插入图片描述

[DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',
                        max_depth=None, max_features=None, max_leaf_nodes=None,
                        min_impurity_decrease=0.0, min_samples_leaf=1,
                        min_samples_split=2, min_weight_fraction_leaf=0.0,
                        random_state=0, splitter='best'),
 LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                    intercept_scaling=1, l1_ratio=None, max_iter=1000,
                    multi_class='auto', n_jobs=None, penalty='l2',
                    random_state=0, solver='lbfgs', tol=0.0001, verbose=0,
                    warm_start=False)]
pull()

在这里插入图片描述

# 定义一个Scores类
class Scores:
    # 定义一个名为score_dummy2的方法,用于计算得分
    # 参数y_true表示真实标签,y_prob表示预测概率,axis表示轴
    def score_dummy2(self, y_true, y_prob, axis=0):
        return 1.0

# 创建一个Scores对象
scores = Scores()

# 添加一个指标
add_metric(
    id='mydummy2',  # 指标的唯一标识符
    name='DUMMY2',  # 指标的名称
    score_func=scores.score_dummy2,  # 指标的计算函数
    target='pred_proba',  # 指标的目标值,这里是预测概率
    greater_is_better=True,  # 指标的得分越大越好
)
Name                                                            DUMMY2
Display Name                                                    DUMMY2
Score Function       <bound method Scores.score_dummy2 of <__main__...
Scorer               make_scorer(score_dummy2, needs_proba=True, er...
Target                                                      pred_proba
Args                                                                {}
Greater is Better                                                 True
Multiclass                                                        True
Custom                                                            True
Name: mydummy2, dtype: object

# 调用compare_models函数,传入参数include=test_models、n_select=2、sort="DUMMY2"和parallel=FugueBackend("dask")
compare_models(include=test_models, n_select=2, sort="DUMMY2", parallel=FugueBackend("dask"))

在这里插入图片描述

[DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',
                        max_depth=None, max_features=None, max_leaf_nodes=None,
                        min_impurity_decrease=0.0, min_samples_leaf=1,
                        min_samples_split=2, min_weight_fraction_leaf=0.0,
                        random_state=0, splitter='best'),
 LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                    intercept_scaling=1, l1_ratio=None, max_iter=1000,
                    multi_class='auto', n_jobs=None, penalty='l2',
                    random_state=0, solver='lbfgs', tol=0.0001, verbose=0,
                    warm_start=False)]
# 这是一个函数定义,函数名为pull
def pull():
    # 这是一个空函数,没有任何代码
    pass

在这里插入图片描述

(7) Spark设置

强烈建议每个Spark执行器上只有一个worker,这样worker可以充分利用所有的CPU(设置spark.task.cpus)。当你这样做时,你应该明确地在setup中设置n_jobs为每个执行器的CPU数量。

executor_cores = 4

spark = SparkSession.builder.config("spark.task.cpus", executor_cores).config("spark.executor.cores", executor_cores).getOrCreate()

setup(data=get_data("juice", verbose=False, profile=False), target = 'Purchase', session_id=0, n_jobs=executor_cores)

compare_models(n_select=2, parallel=FugueBackend(spark))

(8) Dask

Dask有假分布式模式,例如默认的(多线程)和多进程模式。默认模式可以正常工作(但实际上是按顺序运行的),而多进程模式目前对PyCaret不起作用,因为它会干扰PyCaret的全局变量。另一方面,任何Spark执行模式都可以正常工作。

(9) 本地并行化

对于尝试非平凡数据和模型的实际用途,本地并行化(最简单的方法是使用上面显示的本地Dask作为后端)通常没有性能优势。因为在训练过程中很容易超载CPU,增加资源争用。本地并行化的价值在于验证代码,并让你相信分布式环境将在更短的时间内提供预期的结果。

(10) 如何开发

分布式系统很强大,但你必须遵循一些良好的实践来使用它们:

  1. 从小到大: 最初,你必须从一小组数据开始,例如在compare_model中将你想尝试的模型限制为一小组廉价模型,当你验证它们工作正常后,可以切换到更大的模型集合。
  2. 从本地到分布式: 你应该按照这个顺序进行:先在本地验证小数据,然后在分布式环境下验证小数据,最后在分布式环境下验证大数据。当前的设计使过渡无缝。你可以按顺序进行这些操作:parallel=None -> parallel=FugueBackend() -> parallel=FugueBackend(spark)。在第二步中,你可以替换为本地的SparkSession或本地的dask。

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

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

相关文章

7.5组合总和②(LC40-M)

算法&#xff1a; 相比于上一题&#xff0c;数组candidates有重复元素&#xff0c;而要求不能有重复的组合&#xff0c;所以相对于39.组合总和 (opens new window)难度提升了不少。 如何去重&#xff1f; 先把candidates排序&#xff0c;让重复的元素都在一起 单层递归时&a…

MATLAB - 读取双摆杆上的 IMU 数据

系列文章目录 前言 本示例展示了如何从安装在双摆杆上的两个 IMU 传感器生成惯性测量单元 (IMU) 读数。双摆使用 Simscape Multibody™ 进行建模。有关使用 Simscape Multibody™ 构建简易摆的分步示例&#xff0c;请参阅简易摆建模&#xff08;Simscape Multibody&#xff09…

深度学习(七):bert理解之输入形式

传统的预训练方法存在一些问题&#xff0c;如单向语言模型的局限性和无法处理双向上下文的限制。为了解决这些问题&#xff0c;一种新的预训练方法随即被提出&#xff0c;即BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;。通过在大规模…

python通过JS逆向采集艺恩电影数据, 并制作可视化

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 环境使用: 版 本&#xff1a; python 3.10 编辑器&#xff1a;pycharm 2022.3.2 nodejs 模块使用: requests -> pip install requests execjs -> pip install…

python实现bp神经网络对csv文件进行数据预测

参考资源&#xff1a; sklearn库 bp神经网络[从原理到代码一篇搞定]&#xff08;2&#xff09;_sklearn 神经网络-CSDN博客 十分钟上手sklearn&#xff1a;安装&#xff0c;获取数据&#xff0c;数据预处理 - 知乎 (zhihu.com) 一个实例讲解如何使用BP神经网络(附代码) - 知…

基于STM32单片机智能手环老人防跌倒报警系统GSM短信上报毕业设计7

STM32单片机老人防跌倒报警系统GSM短信上报加速度7 演示视频&#xff08;复制到浏览器打开&#xff09;&#xff1a; 基于STM32单片机的智能手环老人防跌倒报警系统设计GSM短信上报ADXL345重力加速度检测设计DIY开发板套件7 修改接收短信手机号码视频&#xff1a; ★★★如何修…

Pycharm解释器的配置: System Intgerpreter 、Pipenv Environment、Virtualenv Environment

文章目录 前提1. 环境准备2. 了解虚拟环境 一、进入Interpreter设置页二、添加Interpreter1. 方式一2. 方式二 三、 System Interpreter四、 Pipenv Environment前提条件&#xff1a;详细步骤1&#xff09; 选择pipenv2&#xff09; 设置Base Interpreter3&#xff09; 设置Pip…

必学的maven的起步

Maven的简介 maven是什么 Maven的本质是一个项目管理工具将项目开发和管理过程抽象成一个项目对象模型&#xff08;POM&#xff09;POM&#xff1a;项目对象模型 Maven的作用&#xff1a; 项目构建&#xff1a;提供标准的、跨平台的自动化项目构建方式依赖管理&#xff1a;方…

mingw下编译opencv4.5.2

初衷&#xff1a; 加载之前的模型没问题&#xff0c;但最近加载另一个模型时出现报错&#xff1a; OpenCV: terminate handler is called! The last OpenCV error is: OpenCV(4.1.0) Error: Assertion failed (nodesMapIt ! nodesMap.end()) in sortByExecutionOrder, file G…

R软件包ConsensusCluster进行共识聚类(Consensus Clustering)

从下面论文看到这个方法&#xff1a; Wang, Xin, et al. "Deep learning using bulk RNA-seq data expands cell landscape identification in tumor microenvironment." Oncoimmunology 11.1 (2022): 2043662. 这篇论文基于 AI 方法对 bulk RNA-seq 数据识别肿瘤微环…

qt项目-《图像标注软件》源码阅读笔记-Shape类绘图及其子类

目录 1. Shape 概览 2. Shape 基类 2.1 字段 2.2 方法 2.3 嵌套类型 3. Shape2D 2d形状纯虚基类 3.1 字段 3.2 方法 4. Shape3D 3d形状纯虚基类 5. Shape2D子类 5.1 Rectangle 矩形类 1. Shape 概览 功能&#xff1a;Shape类及其子类负责形状的绘制及形状的存储。…

【数据结构入门精讲 | 第十三篇】考研408、公司面试树专项练习(二)

在上一篇中我们进行了树的判断题、选择题、填空题专项练习&#xff0c;在这一篇中我们将进行编程题的相关练习。 目录 编程题R7-1 目录树R7-1 是否同一棵二叉搜索树R7-2 二叉搜索树的结构R7-3 平衡二叉树的根R7-1 完全二叉搜索树R7-1 修理牧场R7-2 嘴强王者R7-3 房屋分拆R7-4 动…

Qt/QML编程学习之心得:在QML中调用fileDialog(十六)

Qt中有一些内置的对话框dialog,比如 在QWidget工程中使用比较容易,比如 #include <QFileDialog>fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)")); 那么在QM…

【LearnOpenGL基础入门——5】着色器

目录 一.简介 二.GLSL 三.数据类型 四.输入与输出 五.Uniform 六.更多属性 一.简介 着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说&#xff0c;着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立…

最新技术整理3款开源免费直播推流工具,实现实时视频推流、视频拉流,目标端可以是服务器、云平台、移动设备等(附源码)

最新技术整理3款开源免费直播推流工具&#xff0c;实现实时视频推流、视频拉流&#xff0c;目标端可以是服务器、云平台、移动设备等&#xff08;附源码&#xff09;。 什么是推流&#xff1f; 视频推流是指将实时的视频数据从一个源端发送到一个或多个目标端的过程。推流的源…

基于javaWeb的高校后勤报修系统的设计与实现论文

基于JavaWeb的高校后勤报修系统的设计与实现 摘 要 当下&#xff0c;正处于信息化的时代&#xff0c;许多行业顺应时代的变化&#xff0c;结合使用计算机技术向数字化、信息化建设迈进。以前学校对于后勤报修信息的管理和控制&#xff0c;采用人工登记的方式保存相关数据&…

python脚本 ssh工具 ssh上传文档 选择文档并上传到ssh服务器

此文分享一个python脚本,用于快速的定位、选择文档,并将其上传到指定的ssh服务器。 效果演示 🔥完整演示效果 👇第一步,显然,我们需要选择功能 👇第二步,我们需要定位并选择需要上传的文档 👇第三步,确认我们需要上传文档的ssh服务器 👇第四步,定位、选择…

mybatis的一级缓存使用以及禁用

目录 验证代码如下 mappper 代码 xml 中代码 实际执行代码 执行结果 DefaultSqlSession CachingExecutor BaseExecutor PerpetualCache 总结 禁用一级缓存 mapper 对应的 xml 的 select 查询设置 flushCache 属性为 true MappedStatement 的内部类 Builder 向外部变…

parseInt(0.0000005)大于等于5

文章目录 一、前言二、parseInt()的神秘行为三、解决parseInt()的奥秘四、结论五、最后 一、前言 parseInt() 是 JavaScript 的内置函数&#xff0c;用于解析数字字符串中的整数。例如&#xff0c;从数字字符串中解析整数100&#xff1a; const number parseInt(100); numbe…

Netty-3-封帧

实际上&#xff0c;数据的封帧与解帧本身虽然实现起来十分简单&#xff0c;但它们在本质上仍然是数据的一种编解码。 那么它们相比之前介绍的数据编解码有什么区别呢&#xff1f;单从编码目标看&#xff0c;之前介绍的数据编解码是为了对用户的数据对象进行传输。 封帧与解帧则…