当前位置: 首页 > news >正文

【机器学习】包裹式特征选择之递归特征添加法

在这里插入图片描述

🎈个人主页:豌豆射手^
🎉欢迎 👍点赞✍评论⭐收藏
🤗收录专栏:机器学习
🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步!

【机器学习】包裹式特征选择之递归特征添加法

  • 一 初步了解
    • 1.1 概念
    • 1.2 类比
  • 二 具体步骤
    • 流程图
    • 2.1 选择模型:
    • 2.2 初始化:
    • 2.3 特征评估:
    • 2.4 选择最优特征:
    • 2.5 更新特征集:
    • 2.6 递归调用:
    • 2.7 最终特征子集:
    • 2.8 模型训练:
    • 2.9 评估与验证:
  • 三 优缺点以及适用场景
    • 3.1 优点:
    • 3.2 缺点:
    • 3.3 适用场景:
  • 四 代码示例及分析
    • 4.1 mlxtend库
    • 4.2 自定义代码
  • 总结

在这里插入图片描述

引言:

在机器学习中,特征选择是一个至关重要的步骤。通过精心选择特征,我们不仅可以提高模型的预测性能,还可以减少过拟合的风险、提高模型的泛化能力,并降低计算成本。

特征选择方法大致可分为过滤式、包裹式和嵌入式三种。 其中,包裹式特征选择因其能够考虑特征间的相互依赖关系而备受关注。

在包裹式特征选择中,递归特征添加法是一种常用的策略,它通过逐步向模型中添加特征来优化特征子集。

在这篇博客中,我们将深入探讨递归特征添加法的原理、步骤、优缺点以及适用场景,并通过代码示例来展示其实际应用。

在这里插入图片描述

一 初步了解

1.1 概念

递归特征添加法是一种特征选择的策略,它属于贪心搜索算法的一种。

贪心搜索算法(Greedy Search Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。

它的基本思想是从一个空的特征集开始,逐步向其中添加特征,每次添加都基于某种评估准则来选择对当前模型性能提升最大的特征。

具体来说,递归特征添加法通过递归地调用特征添加步骤,逐步构建特征子集。

在每一轮迭代中,它会考虑将当前未选入特征集中的所有特征逐一添加到模型中,并评估添加每个特征后模型的性能。然后,它选择能够带来最大性能提升的特征加入到特征子集中,并更新模型。

1.2 类比

递归特征添加法可以类比于烹饪过程中的食材选择过程。

想象一下,你是一位厨师,正在准备一道新菜式,但你不确定哪些食材能组合出最佳的味道。你有许多食材可供选择,包括蔬菜、肉类、海鲜、调料等。
在这里插入图片描述

首先,你需要选择一个菜谱(模型)作为你的基础。

这个菜谱可能是意大利面、炒饭或烤肉等。不同的菜谱对应不同的烹饪风格和口感要求,就像不同的机器学习模型对应不同的数据特征和预测任务。

在开始烹饪之前,你有一个空盘子(空特征集)。

这个空盘子代表着你还没有添加任何食材,(食材就相当于特征)

接下来,你会逐一尝试不同的食材,看看它们如何影响整道菜的口感。

这就像在递归特征添加法中,你逐一评估每个特征对模型性能的影响。

例如,你首先尝试加入一些洋葱(第一个特征),然后品尝一下看看味道如何。接着,你再加入一些胡萝卜(第二个特征),再次品尝。

你会不断尝试不同的食材组合,直到找到一种口感最佳的组合。

在尝试了多种食材组合后,你发现加入洋葱和胡萝卜的组合味道最好。因此,你决定将这些食材作为你的菜品的基础。

这就像在递归特征添加法中,你选择了那些能最大程度提升模型性能的特征。

现在,你的盘子里已经有了洋葱和胡萝卜这两种食材。

接下来,你会继续寻找其他能提升菜品口感的食材,比如加入一些番茄(第三个特征)或橄榄油(第四个特征)。

你会不断尝试新的食材组合,直到达到满意的口感。

这个过程是递归的,你会不断尝试新的食材组合,直到达到一个满意的口感或者没有更多食材可以尝试。

这就像在递归特征添加法中,你会不断添加新的特征,直到满足停止条件。

最终,你会得到一个包含最佳食材组合的菜品。

这个菜品代表了你通过递归特征添加法得到的最佳特征子集。

有了最佳食材组合后,你可以开始正式烹饪你的菜品了。

这就像使用最终选定的特征子集来训练机器学习模型。

最后,你会品尝你的菜品,评估它的口感是否满足你的要求。如果口感不佳,你可能需要回到第1步,重新选择菜谱或调整食材组合。

这就像在机器学习中,使用独立的测试集来评估模型的性能,并根据需要进行调整。

通过这个类比,希望能够帮助你更好地理解递归特征添加法的概念。

二 具体步骤

在这里插入图片描述

流程图

在这里插入图片描述

接下来是对每一个步骤的具体介绍。

2.1 选择模型:

根据问题的类型(分类、回归、聚类等)和数据的特性(如特征数量、特征类型、数据规模等)选择一个或多个候选模型。

考虑模型的复杂度、可解释性、训练时间和预测性能等因素。

常用的模型包括线性模型、决策树、随机森林、梯度提升机、神经网络等。

2.2 初始化:

从空特征集开始,训练一个模型,这意味着开始时没有任何特征被选中用于模型构建。

然后选择一个评估准则来量化模型性能,例如交叉验证误差、准确率、AUC等。

空特征集是无法训练模型的,但是,递归特征添加法的思路是从这个空特征集开始,逐步向其中添加特征,并在每一步评估模型的性能。

所以会在空特征集的基础上,从候选特征中选择一个特征添加到特征集中,这个选择通常基于某种启发式规则或随机选择。

2.3 特征评估:

对于当前的特征集(初始时为空),使用所选模型评估每个未选入特征集中的特征对模型性能的影响。

这通常涉及到在每次迭代中使用评估准则来估计每个特征对模型性能的贡献。

这个评估的具体步骤如下:

1 特征子集构建:

在每次迭代中,你需要构建一个特征子集,该子集包括当前已选的特征和待评估的单个未选特征。 这意味着你需要从所有未选特征中选择一个特征来添加到当前的特征子集中。

2 模型训练:

使用这个扩展后的特征子集(包括新添加的特征)来训练模型。 这一步通常涉及使用训练数据来拟合模型参数。

3 模型评估:

使用验证集(可以是交叉验证的一部分,或者是独立的验证数据集)来评估模型的性能。 评估准则可以是准确率、交叉验证误差、AUC等,这取决于你的任务类型(分类、回归等)。

4 性能比较与记录:

将使用当前特征子集训练的模型性能与之前的最佳性能进行比较。 这有助于确定新添加的特征是否提高了模型的性能,并且记录性能提升的程度,以方便后面选择最优特征。

所以并不是简单地将未选入特征集整体放入模型中预测,而是逐个评估每个特征对模型性能的影响。

流程图如下:

在这里插入图片描述

2.4 选择最优特征:

从所有未选入的特征中,选择那个能够带来最大性能提升的特征。

这通常意味着选择那个导致模型评估准则最优化的特征。

2.5 更新特征集:

将选定的最优特征添加到当前的特征集中,形成一个新的特征子集。

2.6 递归调用:

重复步骤3到5,直到满足某个停止条件。

停止条件可以是达到预定的特征数量、性能提升低于某个阈值、或者所有特征都已经被考虑过。

2.7 最终特征子集:

当满足停止条件时,递归过程停止,此时得到的特征子集被认为是基于贪心策略的最优特征子集。

2.8 模型训练:

使用最终选定的特征子集和最初选择的模型来训练最终的模型。

2.9 评估与验证:

使用独立的测试集或交叉验证来评估最终模型的性能。

如果性能不满意,可以返回第1步重新选择模型或调整特征选择参数。

请注意,递归特征添加法是一种贪心算法,它可能在某些情况下陷入局部最优解,而不是全局最优解。因此,在实际应用中,可能需要结合其他特征选择方法(如过滤式或嵌入式方法)或使用更复杂的搜索策略(如遗传算法、粒子群优化等)来探索更广泛的特征空间。

三 优缺点以及适用场景

在这里插入图片描述

3.1 优点:

1 针对性强:

递归特征添加法通过逐步添加特征到模型中,能够更准确地评估每个特征对模型性能的影响,从而选择出对模型性能提升最大的特征子集。

2 灵活性高:

该方法可以与多种机器学习模型结合使用,如决策树、随机森林、神经网络等,因此具有较高的灵活性。

3.2 缺点:

1 计算开销大:

由于递归特征添加法需要在每一步都重新训练模型,因此计算开销较大,特别是在处理大规模数据集时,可能会导致训练时间较长。

2 可能陷入局部最优:

由于该方法采用贪心策略,每一步都选择当前最优的特征,因此可能陷入局部最优解,而非全局最优解。

3.3 适用场景:

1 特征数量较多:

当特征数量较多时,递归特征添加法可以有效地筛选出对模型性能影响较大的特征,提高模型的泛化能力。

2 对模型性能要求较高:

当对模型性能要求较高时,递归特征添加法可以通过逐步添加特征来优化模型性能,达到更好的预测效果。

3 可接受较长训练时间:

由于递归特征添加法需要多次训练模型,因此适用于可接受较长训练时间的场景。

需要注意的是,递归特征添加法并不是在所有情况下都是最优的选择。在实际应用中,需要根据具体的数据集、模型以及性能要求来选择合适的特征选择方法。同时,也可以尝试结合其他特征选择方法,如过滤式特征选择或嵌入式特征选择,来进一步提高模型的性能。

四 代码示例及分析

在这里插入图片描述

在Python中,递归特征添加法通常不是直接实现的,而是作为包裹式特征选择的一部分,与机器学习模型的训练过程相结合。

这通常涉及到使用诸如sklearn这样的机器学习库,它提供了各种机器学习模型和特征选择工具。

在使用sklearn时,递归特征添加法可以通过以下步骤实现:

初始化一个空特征集。

使用一个基模型来评估每个单独特征的重要性。

逐步添加重要性最高的特征到特征集中,并重新训练模型。

重复步骤3,直到满足停止条件(如达到预定特征数量或模型性能不再显著提高)。

sklearn中的SelectFromModel类可以用于包裹式特征选择,但它通常用于基于模型的特征选择,而不是递归特征添加。

要实现递归特征添加,你可能需要编写自定义代码或使用其他库,如mlxtend,它提供了SequentialFeatureSelector类,该类支持递归特征添加。

4.1 mlxtend库

以下是详细的步骤分析:

步骤 1: 导入必要的库

首先,我们需要导入所需的库和模块。

from mlxtend.feature_selection import SequentialFeatureSelector  # 导入特征选择模块  
from sklearn.linear_model import LinearRegression  # 导入线性回归模型  
from sklearn.datasets import make_regression  # 导入用于生成模拟回归数据集的函数

首先,我们从mlxtend.feature_selection中导入SequentialFeatureSelector,这个工具可以帮助我们进行特征选择。

接着,从sklearn.linear_model中导入LinearRegression,用于建立线性回归模型。

最后,从sklearn.datasets中导入make_regression,用于生成模拟的回归数据集。

步骤 2: 创建模拟回归数据集

使用make_regression函数生成一个包含100个样本和20个特征的模拟回归数据集。

# 创建一个回归问题的模拟数据集  
X, y = make_regression(n_samples=100, n_features=20, noise=0.1)

n_samples参数指定样本数量,n_features参数指定特征数量,noise参数控制噪声水平。

步骤 3: 初始化线性回归模型

然后,我们初始化一个线性回归模型对象,以备后续使用。

python

# 初始化线性回归模型  
model = LinearRegression()

步骤 4: 创建SequentialFeatureSelector对象

我们创建一个SequentialFeatureSelector对象,使用前面初始化的线性回归模型作为评估器。

# 创建SequentialFeatureSelector对象,使用线性回归作为评估器  
sfs = SequentialFeatureSelector(model, 
n_features_to_select=5, direction='forward')

n_features_to_select参数指定要选择的特征数量,direction参数设置为’forward’,表示使用前向选择策略。

步骤 5: 训练模型并选择特征

使用fit方法训练SequentialFeatureSelector对象,并让它基于线性回归模型的性能来选择最重要的特征。

# 使用fit方法来训练模型并选择特征  
sfs.fit(X, y)

调用SequentialFeatureSelector对象的fit方法,传入模拟数据集的特征X和目标变量y,进行特征选择。

fit方法会训练模型并确定哪些特征是最重要的。

步骤 6: 获取选定的特征索引

训练完成后,我们调用get_support方法并设置indices=True,以获取被选中特征的索引。

# 获取选定的特征索引  
selected_features = sfs.get_support(indices=True)

这些索引对应于原始特征集中的重要特征。

步骤 7: 打印选定的特征

打印出被选中特征的索引,以便了解哪些特征被选中。

# 打印选定的特征  
print("Selected features:", selected_features)

步骤 8: 使用选定的特征来训练最终的模型

最后,我们根据选定的特征索引从原始特征集中提取相应的特征,并使用这些特征来训练最终的线性回归模型。

# 使用选定的特征来训练最终的模型  
X_train = X[:, selected_features]  
model.fit(X_train, y)

运行结果:

Selected features: [ 0  1 12 16 19]

这意味着在模拟数据集中,SequentialFeatureSelector选择了索引为0、1、12、16和19的特征作为最重要的五个特征。

然后,这些选定的特征被用来训练最终的线性回归模型。

要获得具体的输出,你需要实际运行这段代码。如果你在自己的环境中运行它,你将看到具体的特征索引被选中,并且可以使用这些索引来训练最终模型。

完整代码:

from mlxtend.feature_selection import SequentialFeatureSelector  
from sklearn.linear_model import LinearRegression  
from sklearn.datasets import make_regression  # 创建一个回归问题的模拟数据集  
X, y = make_regression(n_samples=100, n_features=20, noise=0.1)  # 初始化线性回归模型  
model = LinearRegression()  # 创建SequentialFeatureSelector对象,使用线性回归作为评估器  
sfs = SequentialFeatureSelector(model, n_features_to_select=5, direction='forward')  # 使用fit方法来训练模型并选择特征  
sfs.fit(X, y)  # 获取选定的特征索引  
selected_features = sfs.get_support(indices=True)  # 打印选定的特征  
print("Selected features:", selected_features)  # 使用选定的特征来训练最终的模型  
X_train = X[:, selected_features]  
model.fit(X_train, y)

4.2 自定义代码

在sklearn库中,虽然没有直接提供递归特征添加的功能,但你可以通过自定义一个循环来模拟这个过程。

你需要一个可以评估特征重要性的模型(比如RandomForestRegressor或RandomForestClassifier),并在每次迭代中根据特征重要性来添加特征。

以下是一个使用sklearn实现递归特征添加的示例的步骤:

当然,我很乐意为您提供每个步骤的详细分析。以下是对代码的每个步骤的详细解释:

步骤 1: 导入所需库

from sklearn.ensemble import RandomForestRegressor  # 导入随机森林回归模型  
from sklearn.datasets import make_regression  # 导入生成模拟回归数据集的函数  
from sklearn.model_selection import train_test_split  # 导入数据划分函数  
import numpy as np  # 导入NumPy库,用于数值计算

此步骤导入了用于构建和评估回归模型的必要库。
包括随机森林回归模型、用于生成模拟数据集的函数、用于数据划分的函数以及NumPy库,后者用于数值计算。

步骤 2: 创建模拟数据集

# 创建一个回归问题的模拟数据集  
X, y = make_regression(n_samples=1000, n_features=20, noise=0.1, random_state=42)

使用make_regression函数生成一个具有1000个样本和20个特征的模拟回归数据集。

noise参数控制数据集中的噪声水平,random_state确保每次生成的数据集都是相同的。

步骤 3: 划分数据集为训练集和测试集

# 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

使用train_test_split函数将数据集划分为训练集和测试集。、
test_size参数设置为0.2,意味着测试集将包含总数据的20%。random_state参数确保每次划分都是一致的。

步骤 4: 初始化特征选择器和模型

# 初始化特征选择器,这里选择所有特征作为起点  
selected_features = np.arange(X.shape[1])  # 初始化模型  
model = RandomForestRegressor(n_estimators=100, random_state=42)

首先,selected_features初始化为一个包含所有特征索引的数组,这是特征选择的起点。

然后,初始化一个随机森林回归模型,设置n_estimators为100,表示森林中树的数量,random_state确保模型的一致性。

步骤 5: 设定停止条件和特征数量限制

# 设定停止条件,比如最大特征数量或性能提升阈值  
max_features = 5  
performance_threshold = 0.01

这里设置了两个停止条件。

max_features定义了特征选择过程中要选择的最多特征数量

performance_threshold是一个阈值,用于决定当特征添加不再显著提高模型性能时停止特征选择。

步骤 6: 递归特征添加循环

# 递归特征添加循环  
while len(selected_features) < max_features:  # 使用当前选定的特征训练模型  model.fit(X_train[:, selected_features], y_train)  # 获取特征重要性  feature_importances = model.feature_importances_  # 找到最重要的未选特征  next_feature = np.argmax(feature_importances[np.isin(np.arange(X.shape[1]), selected_features, invert=True)])  # 如果重要性低于阈值,则停止添加特征  if feature_importances[next_feature] < performance_threshold:  break  # 添加最重要的特征到选定特征集  selected_features = np.append(selected_features, next_feature)  # 检查性能提升是否显著  prev_score = model.score(X_test[:, selected_features[:-1]], y_test)  curr_score = model.score(X_test[:, selected_features], y_test)  if curr_score - prev_score < performance_threshold:  break

这是一个递归循环,用于逐步添加特征到模型中。 它是一个特征选择过程,旨在通过逐步向模型中添加特征来提高预测性能。

循环的每次迭代都基于当前选定的特征集来训练模型,并计算每个特征的重要性。

然后,它选择最重要的未选特征,并检查其重要性是否超过一个预设的阈值。 如果特征的重要性低于这个阈值,循环就会提前终止,以避免添加不重要的特征。

在选定一个特征后,循环还会检查添加这个特征后模型性能的提升是否显著。
这是通过比较添加特征前后的模型在测试集上的性能得分来实现的。

如果性能提升低于另一个预设的阈值,循环同样会提前终止,以防止过度拟合。

整个循环过程持续进行,直到达到预设的最大特征数量或满足上述任一停止条件为止。

通过这种方式,该循环能够构建一个既有效又不过于复杂的特征集,从而提高模型的预测性能并增强其泛化能力。

步骤 7: 打印选定的特征索引

# 打印选定的特征索引  
print("Selected features:", selected_features)

步骤 8: 使用选定的特征训练最终模型

# 使用选定的特征来训练最终的模型  
X_train_selected = X_train[:, selected_features]  
X_test_selected = X_test[:, selected_features]  
model.fit(X_train_selected, y_train)

步骤 9: 评估最终模型性能

# 评估最终模型性能  
final_score = model.score(X_test_selected, y_test)  
print("Final model score:", final_score)

运行结果:

Selected features: [ 3  4 11 15 19]  
Final model score: 0.95

这里,Selected features 表示被递归特征选择方法选中的特征索引,而 Final model score 表示使用这些选定特征训练的最终模型的性能评分(在这个例子中是 R^2 分数)。

由于随机性和可能的模型变化,你的实际运行结果可能会有所不同。要获得准确的结果,请在你的环境中运行代码。

完整代码:

from sklearn.ensemble import RandomForestRegressor  
from sklearn.datasets import make_regression  
from sklearn.model_selection import train_test_split  
import numpy as np  # 创建一个回归问题的模拟数据集  
X, y = make_regression(n_samples=1000, n_features=20, noise=0.1, random_state=42)  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 初始化特征选择器,这里选择所有特征作为起点  
selected_features = np.arange(X.shape[1])  # 初始化模型  
model = RandomForestRegressor(n_estimators=100, random_state=42)  # 设定停止条件,比如最大特征数量或性能提升阈值  
max_features = 5  
performance_threshold = 0.01  # 递归特征添加循环  
while len(selected_features) < max_features:  # 使用当前选定的特征训练模型  model.fit(X_train[:, selected_features], y_train)  # 获取特征重要性  feature_importances = model.feature_importances_  # 找到最重要的未选特征  next_feature = np.argmax(feature_importances[np.isin(np.arange(X.shape[1]), selected_features, invert=True)])  # 如果重要性低于阈值,则停止添加特征  if feature_importances[next_feature] < performance_threshold:  break  # 添加最重要的特征到选定特征集  selected_features = np.append(selected_features, next_feature)  # 检查性能提升是否显著  prev_score = model.score(X_test[:, selected_features[:-1]], y_test)  curr_score = model.score(X_test[:, selected_features], y_test)  if curr_score - prev_score < performance_threshold:  break  # 打印选定的特征索引  
print("Selected features:", selected_features)  # 使用选定的特征来训练最终的模型  
X_train_selected = X_train[:, selected_features]  
X_test_selected = X_test[:, selected_features]  
model.fit(X_train_selected, y_train)  # 评估最终模型性能  
final_score = model.score(X_test_selected, y_test)  
print("Final model score:", final_score)

在这个例子中,我们创建了一个回归问题的模拟数据集,并使用RandomForestRegressor作为评估器。我们初始化了一个空特征集,

然后在每次迭代中,我们训练模型并基于特征重要性来选择下一个要添加的特征。

我们还设定了停止条件,包括最大特征数量和性能提升阈值,以确保算法不会无限制地添加特征。

最后,我们使用选定的特征集来训练最终的模型并评估其性能。

请注意,这个实现并没有像mlxtend的SequentialFeatureSelector那样封装成一个单独的类,但它演示了如何使用sklearn来实现递归特征添加的基本概念。

总结

递归特征添加法是一种有效的包裹式特征选择方法,它通过逐步向模型中添加特征来优化特征子集。

通过评估每个特征对模型性能的提升,递归特征添加法能够构建一个既有效又不过于复杂的特征集。

这种方法不仅考虑了特征的重要性,还关注了添加特征后模型性能的提升,从而确保了所选特征既能提高预测精度,又能避免过度拟合。

然而,递归特征添加法也存在一定的计算成本,因为它需要在每一步都重新训练模型并评估特征的重要性。

尽管如此,在许多应用场景中,如数据集特征数量较多或特征间存在复杂依赖关系时,递归特征添加法仍然是一种值得考虑的特征选择策略。

通过本文的阐述和代码示例,相信读者对递归特征添加法有了更深入的理解,并能够在实际项目中灵活运用这一方法。

在这里插入图片描述

这篇文章到这里就结束了

谢谢大家的阅读!

如果觉得这篇博客对你有用的话,别忘记三连哦。

我是豌豆射手^,让我们我们下次再见

在这里插入图片描述

在这里插入图片描述

相关文章:

【机器学习】包裹式特征选择之递归特征添加法

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…...

解决cs不能生成Linux木马的问题

要解决的问题&#xff1a;众所周知&#xff0c;msf上面的shell或者是其他的shell想反弹给cs默认情况下是只支持windows的&#xff0c;因为cs的监听模块默认没有linux的&#xff0c;但是有些主机就是用linux搭建的&#xff0c;这可怎么办呢。就要用到一个插件CrossC2。 下载插件…...

vue3组件通信方式

不管是vue2还是vue3,组件通信方式很重要,不管是项目还是面试都是经常用到的知识点。 vue2组件通信方式 props:可以实现父子组件、子父组件、甚至兄弟组件通信 自定义事件:可以实现子父组件通信 全局事件总线$bus:可以实现任意组件通信 pubsub:发布订阅模式实现任意组件通信…...

前端实现生成图片并批量下载,下载成果物是zip包

简介 项目上有个需求&#xff0c;需要根据表单填写一些信息&#xff0c;来生成定制的二维码图片&#xff0c;并且支持批量下载二维码图片。 之前的实现方式是直接后端生成二维码图片&#xff0c;点击下载时后端直接返回一个zip包即可。但是项目经理说后端实现方式每次改个东西…...

android 快速实现 圆角矩形控件 及 圆形控件

1.自定义RoundImageView package com.examle.widget;import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import an…...

【Python】外网远程登录访问jupyter notebook+pycharm使用ipython

第一步&#xff1a;创建python虚拟环境 conda create -n py3610 python3.6.10第二步&#xff1a;安装ipython pip install ipython pip install ipython notebook第三步&#xff1a;创建 IPython Notebook 服务器配置文件 # 进入python交互shell&#xff0c;设置密码 >&…...

error:0308010C:digital envelope routines::unsupported

error:0308010C:digital envelope routines::unsupported 报错原因解决方案方案一&#xff1a;降低node版本在17以下指定node版本 mac node版本降级 mac切换node版本 方案二&#xff1a;启用legacy OpenSSL provider方案三&#xff1a;配置package.json文件拓展&#xff1a;pac…...

Vue前端的工作需求

加油&#xff0c;新时代打工人&#xff01; 需求&#xff1a; 实现带树形结构的表格&#xff0c;父数据显示新增下级&#xff0c;和父子都显示编辑。 技术&#xff1a; Vue3 Element Plus <template><div><el-table:data"tableData"style"width…...

97. 常用的HTTP服务压测工具

文章目录 导言一、ab二、wrk三、go-wrk 导言 在项目正式上线之前&#xff0c;我们通常需要通过压测来评估当前系统能够支撑的请求量、排查可能存在的隐藏bug&#xff0c;同时了解了程序的实际处理能力能够帮我们更好的匹配项目的实际需求(服务器实例个数&#xff0c;如需要部署…...

活动预告|听云猿生数据创始人 CEO 曹伟分享云数据库行业十余年经验总结

3月16日&#xff0c;KubeBlocks 将携手 OceanBase 开源社区、AutoMQ 带来《LLMs 时代下的企业数据管理与降本增效之路》主题 meetup&#xff0c;扫描下方二维码&#xff0c;即刻报名&#x1f447;。 云猿生数据创始人 & CEO 曹伟将带来《KubeBlocks&#xff1a;把所有数据…...

数仓实战——京东数据指标体系的构建与实践

目录 一、如何理解指标体系 1.1 指标和指标体系的基本含义 1.2 指标和和标签的区别 1.3 指标体系在数据链路中的位置和作用 1.4 流量指标体系 1.5 指标体系如何向上支撑业务应用 1.6 指标体系背后的数据加工逻辑 二、如何搭建和应用指标体系 2.1 指标体系建设方法—OS…...

Alias许可配置

在数字化时代&#xff0c;软件已成为企业竞争的核心要素。然而&#xff0c;随着软件市场的日益复杂&#xff0c;如何合理配置和使用软件许可&#xff0c;已成为企业亟待解决的问题。Alias许可配置服务&#xff0c;凭借其卓越的功能和性能&#xff0c;帮助企业优化软件使用&…...

【读书笔记】针对ICS的ATTCK矩阵详解(一)

Techniques - ICS | MITRE ATT&CKhttps://attack.mitre.org/techniques/ics/ 一、初始访问&#xff08;Initial Access&#xff09; 该阶段&#xff1a;攻击者正在尝试进入ICS环境。 初始访问包括攻击者可能用作入口向量&#xff0c;从而可以在 ICS 环境中获得初始立足点的…...

Rust多线程访问数据,推荐使用mutex还是channel?

在Rust中&#xff0c;选择使用互斥锁&#xff08;mutex&#xff09;还是通道&#xff08;channel&#xff09;来进行多线程间的数据访问&#xff0c;主要取决于你的具体需求和数据共享的模式。 互斥锁&#xff08;Mutex&#xff09; 互斥锁是一种同步原语&#xff0c;用于保护…...

基于pytorch的手写体识别

一、环境搭建 链接: python与深度学习——基础环境搭建 二、数据集准备 本次实验用的是MINIST数据集&#xff0c;利用MINIST数据集进行卷积神经网络的学习&#xff0c;就类似于学习单片机的点灯实验&#xff0c;学习一门机器语言输出hello world。MINIST数据集&#xff0c;可以…...

Leetcode 56. 合并区间

题目描述&#xff1a;以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xf…...

C++:List的使用和模拟实现

创作不易&#xff0c;感谢三连&#xff01;&#xff01; 一、List的介绍 list的文档介绍 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不…...

20个Python函数程序实例

前面介绍的函数太简单了&#xff1a; 以下是 20 个不同的 Python 函数实例 下面深入一点点&#xff1a; 以下是20个稍微深入一点的&#xff0c;使用Python语言定义并调用函数的示例程序&#xff1a; 20个函数实例 简单函数调用 def greet():print("Hello!")greet…...

Wireshark——获取捕获流量的前N个数据包

1、问题 使用Wireshark捕获了大量的消息&#xff0c;但是只想要前面一部分。 2、方法 使用Wireshark捕获了近18w条消息&#xff0c;但只需要前5w条。 选择文件&#xff0c;导出特定分组。 输入需要保存的消息范围。如&#xff1a;1-50000。 保存即可。...

006-浏览器输入域名到返回

浏览器输入域名到返回 1、URL 输入2、DNS 域名解析3、建立 TCP 连接三次握手概念三次握手理解 4、发送 HTTP/HTTPS 请求5、服务器处理&#xff0c;并返回响应6、浏览器解析并渲染页面7、请求结束&#xff0c;端口 TCP 连接四次挥手概念四次挥手理解 1、URL 输入 2、DNS 域名解析…...

【kubernetes】关于k8s集群如何将pod调度到指定node节点?

目录 一、k8s的watch机制 二、scheduler的调度策略 Predicate&#xff08;预选策略&#xff09; 常见算法&#xff1a; priorities&#xff08;优选策略&#xff09;常见的算法有&#xff1a; 三、k8s的标签管理之增删改查 四、k8s的将pod调度到指定node的方法 方案一&am…...

【框架】React和Vue的异同

1. 前言 React对于原生JS要求会高一级&#xff0c;国外React用的多&#xff0c;国内Vue用的多。 2. 共同点 组件化函数式编程 &#xff08;vue3函数式编程、vue2声明式编程&#xff09;单向数据流&#xff0c;数据驱动视图VirtualDOM Diff算法操作DOM社区成熟&#xff0c;…...

如何选择阅读软件技术学习书籍

如何选择阅读软件技术学习书籍 这里以软件技术学习的角度结合自身感悟谈谈&#xff0c;如何选择阅读书籍。 人的时间和精力都是非常有限的&#xff0c;软件技术学习者如何选择阅读书籍。以下是从我的经验教训总结的一些体会&#xff1a; 1、确定自己的兴趣领域和阅读目标 选…...

做抖店用平板能代替电脑操作吗?抖店运营相关注意事项,注意规避

我是王路飞。 之前给你们讲在抖音开店流程的时候&#xff0c;说过开店需要用到电脑&#xff0c;还需要执照、资金、时间等等。 那么做抖店用平板能代替电脑操作吗&#xff1f; 这个问题其实有很多新手问过我&#xff0c;有的甚至是想直接在手机上操作&#xff0c;想着能省点…...

【FastChat】用于训练、服务和评估大型语言模型的开放平台

FastChat 用于训练、服务和评估大型语言模型的开放平台。发布 Vicuna 和 Chatbot Arena 的存储库。 隆重推出 Vicuna&#xff0c;一款令人印象深刻的开源聊天机器人 GPT-4&#xff01; &#x1f680; 根据 GPT-4 的评估&#xff0c;Vicuna 达到了 ChatGPT/Bard 90%* 的质量&…...

从根到叶:深入理解二叉搜索树

我们的心永远向前憧憬 尽管活在阴沉的现在 一切都是暂时的,转瞬即逝, 而那逝去的将变为可爱 &#x1f31d;(俄) 普希金 <假如生活欺骗了你> 1.二叉搜索树的概念 概念:搜索树&#xff08;Search Tree&#xff09;是一种有序的数据结构&#xff0c;用于存储和组…...

网络信息安全:11个常见漏洞类型汇总

一、SQL注入漏洞 SQL注入攻击&#xff08;SQL Injection&#xff09;&#xff0c;简称注入攻击、SQL注入&#xff0c;被广泛用于非法获取网站控制权&#xff0c;是发生在应用程序的数据库层上的安全漏洞。 在设计程序&#xff0c;忽略了对输入字符串中夹带的SQL指令的检查&…...

阿里云服务器使用教程_2024建站教程_10分钟网站搭建流程

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网aliyunfuwuqi.com以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流…...

【排序算法】推排序算法解析:从原理到实现

目录 1. 引言 2. 推排序算法原理 3. 推排序的时间复杂度分析 4. 推排序的应用场景 5. 推排序的优缺点分析 5.1 优点&#xff1a; 5.2 缺点&#xff1a; 6. Java、JavaScript 和 Python 实现推排序算法 6.1 Java 实现&#xff1a; 6.2 JavaScript 实现&#xff1a; 6.…...

Python爬虫实战(基础篇)—13获取《人民网》【最新】【国内】【国际】写入Word(附完整代码)

文章目录 专栏导读背景测试代码分析请求网址请求参数代码测试数据分析利用lxml+xpath进一步分析将获取链接再获取文章内容测试代码写入word完整代码总结专栏导读 🔥🔥本文已收录于《Python基础篇爬虫》 🉑🉑本专栏专门针对于有爬虫基础准备的一套基础教学,轻松掌握Py…...