Python 机器学习 基础 之 算法链与管道 【通用的管道接口/网格搜索预处理步骤与模型参数/网格搜索选择使用哪个模型】的简单说明

Python 机器学习 基础 之 算法链与管道 【通用的管道接口/网格搜索预处理步骤与模型参数/网格搜索选择使用哪个模型】的简单说明

目录

Python 机器学习 基础 之 算法链与管道 【通用的管道接口/网格搜索预处理步骤与模型参数/网格搜索选择使用哪个模型】的简单说明

一、简单介绍

二、通用的管道接口

三、网格搜索预处理步骤与模型参数

四、网格搜索选择使用哪个模型

附录

一、参考文献


一、简单介绍

Python是一种跨平台的计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。Python是一种解释型脚本语言,可以应用于以下领域: Web 和 Internet开发、科学计算和统计、人工智能、教育、桌面界面开发、软件开发、后端开发、网络爬虫。

Python 机器学习是利用 Python 编程语言中的各种工具和库来实现机器学习算法和技术的过程。Python 是一种功能强大且易于学习和使用的编程语言,因此成为了机器学习领域的首选语言之一。Python 提供了丰富的机器学习库,如Scikit-learn、TensorFlow、Keras、PyTorch等,这些库包含了许多常用的机器学习算法和深度学习框架,使得开发者能够快速实现、测试和部署各种机器学习模型。

Python 机器学习涵盖了许多任务和技术,包括但不限于:

  1. 监督学习:包括分类、回归等任务。
  2. 无监督学习:如聚类、降维等。
  3. 半监督学习:结合了有监督和无监督学习的技术。
  4. 强化学习:通过与环境的交互学习来优化决策策略。
  5. 深度学习:利用深度神经网络进行学习和预测。

通过 Python 进行机器学习,开发者可以利用其丰富的工具和库来处理数据、构建模型、评估模型性能,并将模型部署到实际应用中。Python 的易用性和庞大的社区支持使得机器学习在各个领域都得到了广泛的应用和发展。

二、通用的管道接口

Pipeline 类不但可用于预处理和分类,实际上还可以将任意数量的估计器连接在一起。

在机器学习中,使用管道(Pipeline)和算法链可以让数据预处理、特征选择和模型训练等步骤变得更加简洁和系统化。Scikit-learn 提供了一个通用的管道接口,通过 Pipelinemake_pipeline 来实现。这使得我们可以将多个步骤整合到一起,形成一个统一的工作流。下面是一些主要概念和如何使用通用的管道接口的详细说明。

定义

  1. Pipeline:

    • Pipeline 是一个可以串联多个处理步骤的对象。每个步骤都是一个二元组,包含一个名字和一个估计器(如预处理步骤或模型)。
    • Pipeline 的最后一步必须是一个模型(如分类器或回归器),而中间步骤可以是任何数据转换器(如标准化、特征选择等)。
  2. make_pipeline:

    • make_pipeline 是一个简化的工厂函数,用于创建一个 Pipeline 对象。它自动为每个步骤生成名称,无需手动指定名称。

共同点和区别

  • 共同点:

    • 都可以将多个处理步骤整合到一起。
    • 都提供了统一的接口,可以像单个模型一样进行训练和预测。
    • 都支持超参数的网格搜索和交叉验证。
  • 区别:

    • Pipeline 需要手动为每个步骤指定名称。
    • make_pipeline 自动为每个步骤生成名称,适合步骤较少且名称无关紧要的情况。

使用示例

  1. 使用 Pipeline
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_california_housing# 加载数据
california = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(california.data, california.target, random_state=0)# 创建管道
pipe = Pipeline([('scaler', StandardScaler()),('poly', PolynomialFeatures(degree=2)),('ridge', Ridge())
])# 训练模型
pipe.fit(X_train, y_train)# 评估模型
train_score = pipe.score(X_train, y_train)
test_score = pipe.score(X_test, y_test)print(f"Training score: {train_score:.2f}")
print(f"Test score: {test_score:.2f}")
  1. 使用 make_pipeline
from sklearn.pipeline import make_pipeline# 创建管道
pipe = make_pipeline(StandardScaler(),PolynomialFeatures(degree=2),Ridge()
)# 训练模型
pipe.fit(X_train, y_train)# 评估模型
train_score = pipe.score(X_train, y_train)
test_score = pipe.score(X_test, y_test)print(f"Training score: {train_score:.2f}")
print(f"Test score: {test_score:.2f}")

选择和使用

  • 选择:

    • 使用 Pipeline 当你希望显式地为每个步骤命名时。
    • 使用 make_pipeline 当步骤名称不重要或步骤较少时。
  • 使用:

    • 管道允许你将数据预处理、特征生成和模型训练结合在一起,这样可以减少代码重复和错误。
    • 通过统一的接口,可以在整个数据处理和建模过程中保持一致性。
    • 可以将管道与 GridSearchCVRandomizedSearchCV 结合使用,进行超参数调优。

例如,你可以构建一个包含特征提取、特征选择、缩放和分类的管道,总共有 4 个步骤。同样,最后一步可以用回归或聚类代替分类。

对于管道中估计器的唯一要求就是,除了最后一步之外的所有步骤都需要具有 transform 方法,这样它们可以生成新的数据表示,以供下一个步骤使用。

在调用 Pipeline.fit 的过程中,管道内部依次对每个步骤调用 fittransform (或仅调用 fit_transform 。) ,其输入是前一个步骤中 transform 方法的输出。对于管道中的最后一步,则仅调用 fit

忽略某些细枝末节,其实现方法如下所示。请记住,pipeline.steps 是由元组组成的列表,所以 pipeline.steps[0][1] 是第一个估计器,pipeline.steps[1][1] 是第二个估计器,以此类推:

def fit(self, X, y):X_transformed = Xfor name, estimator in self.steps[:-1]:# 遍历除最后一步之外的所有步骤# 对数据进行拟合和变换X_transformed = estimator.fit_transform(X_transformed, y)# 对最后一步进行拟合self.steps[-1][1].fit(X_transformed, y)return self

使用 Pipeline 进行预测时,我们同样利用除最后一步之外的所有步骤对数据进行变换(transform ),然后对最后一步调用 predict :

def predict(self, X):X_transformed = Xfor step in self.steps[:-1]:# 遍历除最后一步之外的所有步骤# 对数据进行变换X_transformed = step[1].transform(X_transformed)# 利用最后一步进行预测return self.steps[-1][1].predict(X_transformed)

整个过程如图 6-3 所示,其中包含两个变换器(transformer)T1 和 T2 ,还有一个分类器(叫作 Classifier )。

图 6-3:管道的训练和预测过程概述

管道实际上比上图更加通用。管道的最后一步不需要具有 predict 函数,比如说,我们可以创建一个只包含一个缩放器和一个 PCA 的管道。由于最后一步(PCA )具有 transform 方法,所以我们可以对管道调用 transform ,以得到将 PCA.transform 应用于前一个步骤处理过的数据后得到的输出。管道的最后一步只需要具有 fit 方法。

利用上述语法创建管道有时有点麻烦,我们通常不需要为每一个步骤提供用户指定的名称。有一个很方便的函数 make_pipeline ,可以为我们创建管道并根据每个步骤所属的类为其自动命名。make_pipeline 的语法如下所示:

from sklearn.pipeline import make_pipeline
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import SVC# 标准语法
pipe_long = Pipeline([("scaler", MinMaxScaler()), ("svm", SVC(C=100))])
# 缩写语法
pipe_short = make_pipeline(MinMaxScaler(), SVC(C=100))

管道对象 pipe_long 和 pipe_short 的作用完全相同,但 pipe_short 的步骤是自动命名的。我们可以通过查看 steps 属性来查看步骤的名称:

print("Pipeline steps:\n{}".format(pipe_short.steps))
Pipeline steps:
[('minmaxscaler', MinMaxScaler()), ('svc', SVC(C=100))]

这两个步骤被命名为 minmaxscaler 和 svc 。一般来说,步骤名称只是类名称的小写版本。如果多个步骤属于同一个类,则会附加一个数字:

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCApipe = make_pipeline(StandardScaler(), PCA(n_components=2), StandardScaler())
print("Pipeline steps:\n{}".format(pipe.steps))
Pipeline steps:
[('standardscaler-1', StandardScaler()), ('pca', PCA(n_components=2)), ('standardscaler-2', StandardScaler())]

如你所见,第一个 StandardScaler 步骤被命名为 standardscaler-1 ,而第二个被命名为 standardscaler-2 。但在这种情况下,使用具有明确名称的 Pipeline 构建可能更好,以便为每个步骤提供更具语义的名称。

通常来说,你希望检查管道中某一步骤的属性——比如线性模型的系数或 PCA 提取的成分。要想访问管道中的步骤,最简单的方法是通过 named_steps 属性,它是一个字典,将步骤名称映射为估计器:

from sklearn.datasets import load_breast_cancer# 加载并划分数据
cancer = load_breast_cancer()# 用前面定义的管道对cancer数据集进行拟合
pipe.fit(cancer.data)
# 从"pca"步骤中提取前两个主成分
components = pipe.named_steps["pca"].components_
print("components.shape: {}".format(components.shape))
components.shape: (2, 30)

本章前面说过,使用管道的主要原因之一就是进行网格搜索。一个常见的任务是在网格搜索内访问管道的某些步骤。我们对 cancer 数据集上的 LogisticRegression 分类器进行网格搜索,在将数据传入 LogisticRegression 分类器之前,先用 Pipeline 和 StandardScaler 对数据进行缩放。首先,我们用 make_pipeline 函数创建一个管道:

from sklearn.linear_model import LogisticRegression
pipe = make_pipeline(StandardScaler(), LogisticRegression())

接下来,我们创建一个参数网格。我们在第 2 章中说过,LogisticRegression 需要调节的正则化参数是参数 C 。我们对这个参数使用对数网格,在 0.01 和 100 之间进行搜索。由于我们使用了 make_pipeline 函数,所以管道中 LogisticRegression 步骤的名称是小写的类名称 logisticregression 。因此,为了调节参数 C ,我们必须指定 logisticregression__C 的参数网格:

param_grid = {'logisticregression__C': [0.01, 0.1, 1, 10, 100]}

像往常一样,我们将 cancer 数据集划分为训练集和测试集,并对网格搜索进行拟合:

from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCVX_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=4)
grid = GridSearchCV(pipe, param_grid, cv=5)
grid.fit(X_train, y_train)

那么我们如何访问 GridSearchCV 找到的最佳 LogisticRegression 模型的系数呢?我们从第 5 章中知道,GridSearchCV 找到的最佳模型(在所有训练数据上训练得到的模型)保存在 grid.best_estimator_ 中:

print("Best estimator:\n{}".format(grid.best_estimator_))
Best estimator:
Pipeline(steps=[('standardscaler', StandardScaler()),('logisticregression', LogisticRegression(C=1))])

在我们的例子中,best_estimator_ 是一个管道,它包含两个步骤:standardscaler 和 logisticregression 。如前所述,我们可以使用管道的 named_steps 属性来访问 logisticregression 步骤:

print("Logistic regression step:\n{}".format(grid.best_estimator_.named_steps["logisticregression"]))
Logistic regression step:
LogisticRegression(C=1)

现在我们得到了训练过的 LogisticRegression 实例,下面我们可以访问与每个输入特征相关的系数(权重):

print("Logistic regression coefficients:\n{}".format(grid.best_estimator_.named_steps["logisticregression"].coef_))
Logistic regression coefficients:
[[-0.4475566  -0.34609376 -0.41703843 -0.52889408 -0.15784407  0.60271339-0.71771325 -0.78367478  0.04847448  0.27478533 -1.29504052  0.05314385-0.69103766 -0.91925087 -0.14791795  0.46138699 -0.1264859  -0.102894860.42812714  0.71492797 -1.08532414 -1.09273614 -0.85133685 -1.04104568-0.72839683  0.07656216 -0.83641023 -0.64928603 -0.6491432  -0.42968125]]

这个系数列表可能有点长,但它通常有助于理解你的模型。

三、网格搜索预处理步骤与模型参数

我们可以利用管道将机器学习工作流程中的所有处理步骤封装成一个 scikit-learn 估计器。这么做的另一个好处在于,现在我们可以使用监督任务(比如回归或分类)的输出来调节预处理参数 。在前几章里,我们在应用岭回归之前使用了 boston 数据集的多项式特征。下面我们用一个管道来重复这个建模过程。管道包含 3 个步骤:缩放数据、计算多项式特征与岭回归:

from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.linear_model import Ridge
from sklearn.pipeline import make_pipeline# 加载加利福尼亚房价数据集
california = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(california.data, california.target,random_state=0)# 创建管道
pipe = make_pipeline(StandardScaler(),PolynomialFeatures(),Ridge())

我们怎么知道选择几次多项式,或者是否选择多项式或交互项呢?理想情况下,我们希望根据分类结果来选择 degree 参数。我们可以利用管道搜索 degree 参数以及 Ridge 的 alpha 参数。为了做到这一点,我们要定义一个包含这两个参数的 param_grid ,并用步骤名称作为前缀:

param_grid = {'polynomialfeatures__degree': [1, 2, 3],'ridge__alpha': [0.001, 0.01, 0.1, 1, 10, 100]}

现在我们可以再次运行网格搜索:

from sklearn.model_selection import GridSearchCVgrid = GridSearchCV(pipe, param_grid=param_grid, cv=5, n_jobs=-1)
grid.fit(X_train, y_train)

像之前所做的那样,我们可以用热图将交叉验证的结果可视化(见图 6-4):

import matplotlib.pyplot as pltplt.matshow(grid.cv_results_['mean_test_score'].reshape(3, -1),vmin=0, cmap="viridis")
plt.xlabel("ridge__alpha")
plt.ylabel("polynomialfeatures__degree")
plt.xticks(range(len(param_grid['ridge__alpha'])), param_grid['ridge__alpha'])
plt.yticks(range(len(param_grid['polynomialfeatures__degree'])),param_grid['polynomialfeatures__degree'])plt.colorbar()# plt.tight_layout()
plt.savefig('Images/05GridSearchPreprocessingStepsWithModelParameters-01.png', bbox_inches='tight')
plt.show()
图 6-4:以多项式特征的次数和岭回归的 alpha 参数为坐标轴,绘制交叉验证平均分数的热图

从交叉验证的结果中可以看出,使用二次多项式很有用,但三次多项式的效果比一次或二次都要差很多。从找到的最佳参数中也可以看出这一点:

print("Best parameters: {}".format(grid.best_params_))
Best parameters: {'polynomialfeatures__degree': 1, 'ridge__alpha': 10}
print("Test-set score: {:.2f}".format(grid.score(X_test, y_test)))
Test-set score: 0.59

为了对比,我们运行一个没有多项式特征的网格搜索:

param_grid = {'ridge__alpha': [0.001, 0.01, 0.1, 1, 10, 100]}
pipe = make_pipeline(StandardScaler(), Ridge())
grid = GridSearchCV(pipe, param_grid, cv=5)
grid.fit(X_train, y_train)
print("Score without poly features: {:.2f}".format(grid.score(X_test, y_test)))
Score without poly features: 0.59

正与我们观察图 6-4 中的网格搜索结果所预料的那样,不使用多项式特征得到了明显更差的结果。

同时搜索预处理参数与模型参数是一个非常强大的策略。但是要记住,GridSearchCV 会尝试指定参数的所有可能组合 。因此,向网格中添加更多参数,需要构建的模型数量将呈指数增长。

四、网格搜索选择使用哪个模型

你甚至可以进一步将 GridSearchCV 和 Pipeline 结合起来:还可以搜索管道中正在执行的实际步骤(比如用 StandardScaler 还是用 MinMaxScaler )。这样会导致更大的搜索空间,应该予以仔细考虑。尝试所有可能的解决方案,通常并不是一种可行的机器学习策略。但下面是一个例子:在 iris 数据集上比较 RandomForestClassifier 和 SVC 。我们知道,SVC 可能需要对数据进行缩放,所以我们还需要搜索是使用 StandardScaler 还是不使用预处理。我们知道,RandomForestClassifier 不需要预处理。我们先定义管道。这里我们显式地对步骤命名。我们需要两个步骤,一个用于预处理,然后是一个分类器。我们可以用 SVC 和 StandardScaler 来将其实例化:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVCpipe = Pipeline([('preprocessing', StandardScaler()), ('classifier', SVC())])

现在我们可以定义需要搜索的 parameter_grid 。我们希望 classifier 是 RandomForestClassifier 或 SVC 。由于这两种分类器需要调节不同的参数,并且需要不同的预处理,所以我们可以使用之前的“在非网格的空间中搜索”中所讲的搜索网格列表。为了将一个估计器分配给一个步骤,我们使用步骤名称作为参数名称。如果我们想跳过管道中的某个步骤(例如,RandomForest 不需要预处理),则可以将该步骤设置为 None :

from sklearn.ensemble import RandomForestClassifierparam_grid = [{'classifier': [SVC()], 'preprocessing': [StandardScaler(), None],'classifier__gamma': [0.001, 0.01, 0.1, 1, 10, 100],'classifier__C': [0.001, 0.01, 0.1, 1, 10, 100]},{'classifier': [RandomForestClassifier(n_estimators=100)],'preprocessing': [None], 'classifier__max_features': [1, 2, 3]}]

现在,我们可以像前面一样将网格搜索实例化并在 cancer 数据集上运行:

from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_breast_cancer# 加载并划分数据
cancer = load_breast_cancer()X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=0)grid = GridSearchCV(pipe, param_grid, cv=5)
grid.fit(X_train, y_train)print("Best params:\n{}\n".format(grid.best_params_))
print("Best cross-validation score: {:.2f}".format(grid.best_score_))
print("Test-set score: {:.2f}".format(grid.score(X_test, y_test)))
Best params:
{'classifier': SVC(), 'classifier__C': 10, 'classifier__gamma': 0.01, 'preprocessing': StandardScaler()}Best cross-validation score: 0.99
Test-set score: 0.98

网格搜索的结果是 SVC 与 StandardScaler 预处理,在 C=10 和 gamma=0.01 时给出最佳结果。

附录

一、参考文献

参考文献:[德] Andreas C. Müller [美] Sarah Guido 《Python Machine Learning Basics Tutorial》

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

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

相关文章

渗透测试报告生成工具

目录 1.前言 1.1 渗透测试报告是什么? 1.2 渗透测试报告的编写需要考虑以下几点: 1.3 一份优秀的渗透测试报告应该具备以下特点: 1.4 在编写渗透测试报告之前,需要进行一些准备工作: 1.5 渗透测试报告一般包括以下部分&…

字符串和字符串函数(2)

前言: 在字符串和字符串函数(1)-CSDN博客中,已将将字符串和字符函数的使用了解,并且实现模拟了一些字符串的库函数。 接下来将继续深入学习字符串和字符串函数。并且模拟实现一些较为复杂的函数。 可控制字符…

跟着小白学linux的基础命令

小白学习记录: 前情提要:Linux命令基础格式!查看 lsLinux 的7种文件类型及各颜色代表含义 进入指定目录 cd查看当前工作目录 pwd创建一个新的目录(文件夹) mkdir创建文件 touch查看文件内容 cat、more操作文件、文件夹- 复制 cp- 移动 mv- 删…

redis安裝启动

1、下载redis解压 https://github.com/tporadowski/redis/releases 2、打开cmd,切换到解压的文件夹 3、redis-server.exe redis.windows.conf 启动redis redis可通过命令行输入config set requirepass password和直接修改redis.config文件中修改 requirepass 来设…

工业级物联网边缘网关解决方案-天拓四方

随着工业4.0时代的到来,越来越多的企业开始寻求智能化升级,以提高生产效率、降低运营成本并增强市场竞争力。然而,在实际的转型升级过程中,许多企业面临着数据孤岛、设备兼容性差、网络安全风险高等问题,这些问题严重制…

Flink的简单学习二

一 Flink的核心组件 1.1 client 1.将数据流程图DataFlow发送给JobManager。 1.2 JobManager 1.收集client的DataFlow图,将图分解成一个个的task任务,并返回状态更新数据给client 2.JobManager负责作业调度,收集TaskManager的Heartbeat和…

精选网络安全书单:打造数字世界的钢铁长城!

目录 1.前言 2.书单推荐 2.1. 《内网渗透实战攻略》 2.2. 《Kali Linux高级渗透测试(原书第4版)》 2.3. 《CTF那些事儿》 2.4. 《权限提升技术:攻防实战与技巧》 2.5. 《数字政府网络安全合规性建设指南:密码应用与数据安全…

华为鲲鹏应用开发基础: 计算机系统概述(一)

1. 计算机系统演进及分类 1.1 计算机发展的四个阶段 1.2 当前计算机通常分为以下五类: 分类超级计算机大型计算机迷你计算机(服务器)微型计算机工作站特点• 功能最强、运算速度最快、 存储容量最大的计算机 • 多用于国家高科技领域和 尖端技术研究 例如,“神威太湖之光”…

数字智能数字人直播带货软件系统 实现真人形象的1:1克隆 前后端分离 带完整的安装代码包以及搭建教程

系统概述 数字智能数字人直播带货小程序源码系统是一套集人工智能、3D建模、云计算等技术于一体的综合性解决方案。该系统通过深度学习算法,能够实现对真人形象的精准捕捉和1:1克隆,使数字人在直播过程中呈现出与真人无异的表现力。同时,系统…

使用Kimi月之暗面快速完成学术论文【全流程】

学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 国内大型互联网公司如阿里、腾讯、360纷纷开始免费提供长文本生成服务,体验了一把国产级的模型Kimi,小编只有一个感觉:国产AI模型只能说越来越牛逼了…

06- 数组的基础知识详细讲解

06- 数组的基础知识详细讲解 一、基本概念 一次性定义多个相同类型的变量,并且给它们分配一片连续的内存。 int arr[5];1.1 初始化 只有在定义的时候赋值,才可以称为初始化。数组只有在初始化的时候才可以统一赋值。 以下是一些示例规则: …

NocoDB开源的智能表格详解-腾讯文档本地替代品

文章目录 一、介绍二、docker-compose部署三、登录NocoDB四、NocoDB手册1. 创建项目2. 收集统计表2.1 添加字段2.2 编辑字段2.3 字段类型2.4 发布表格 3.创建表单3.1 创建表单3.2 分享表单3.3 填写检测单 4.创建看板5.创建画廊 一、介绍 可作为腾讯文档的本地电子表格替代品&a…

mysql启动出现Error: 2 (No such file or directory)

查看mydql状态 systemctl status mysqlThe designated data directory /var/lib/mysql/ is unusable 查看mysql日志 tail -f /var/log/mysql/error.logtail: cannot open ‘/var/log/mysql/error.log’ for reading: No such file or directory tail: no files remaining 第…

小白跟做江科大32单片机之按键控制LED

原理部分 1.LED部分使用的是这样的连接方式 2.传感器模块的电路图 滤波电容如果接地,一般用于滤波,在分析电路时就不用考虑。下面这个电路就是看A端和B端哪端的拉力大,就能把电压值对应到相应的电压值 比较器部分 如果A端电压>B端电压&am…

Android 图表开发开源库 MPAndroidChart 使用总结

1. 引言 电视项目中需要一个折线图表示节电数据变化情况,类比 H5 来说,Android 中也应该有比较成熟的控件,经过调研后,发现 MPAndroidChart 功能比较强大,网上也有人说可能是目前 Android 开发最好用的一个三方库了&a…

WPS表格插件方方格子【凑数】功能:选出和等于固定数字的数

文章目录 后来发现可以下载方方格子插件,使用【凑数】功能https://ffcell.lanzouj.com/iwhfc1kjhayh【凑数】快速【凑数】 导师让沾发票,需要选出若干个数额的发票,使它们的和等于一个指定数。不知道怎么办了,查了一下&#xff0c…

Python第二语言(四、Python数据容器)

目录 一、 数据容器(list、tuple、str、map、dict) 1. 数据容器概念 2. 列表list( [] ) 2.1 定义方式 2.2 嵌套列表 2.3 list通过获取下标索引获取值 2.4 下标使用概念 2.5 list列表的使用(列表的方法&#xff…

linux nohup命令详解:持久运行命令,无视终端退出

nohup (全称为 “no hang up”),用于运行一个命令,使其在你退出 shell 或终端会话后继续运行。 基本语法 nohup command [arg1 ...] [&> output_file] &command 是你想要运行的命令。[arg1 ...] 是该命令的参数。&am…

快排与归并的算法(非递归版)

一.快排 1.递归法(方法多样) 1>hoare版 注:该方法小编已经在上篇博客中介绍过了,就不在这里过多赘述了,如果有兴趣的小伙伴可以看看小编的上篇博客哦 2>挖坑法 1)方法介绍:定义最左边的数据为key&#xff0…

生信学习入门常见错误可能的原因分类总结和求助指南

文件或目录找不到 这是常见问题,常见提示有 No such file or directory Error in file(file, “rt”):无法打开链接 Fatal error: Unable to open file for reading (seq/WT1_1.fq) Fatal error: Unable to read from file (C:Program file/Git/usea…