AI量化模型预测挑战赛 第二次学习笔记

        有关竞赛信息以及基础baseline代码解读请看我的上一篇文章

AI量化模型预测——baseline学习笔记_寂ღ᭄秋࿐的博客-CSDN博客

         在经过baseline进行详细的分析之后,接下来的方向肯定是奔着提分去的,下面我就从五个方面进行一一列出提分思路

  • 提取更多的特征
  • 特征筛选方案
  • 内存压缩
  • 验证方式
  • 模型集成

一、提取更多的特征

1. 完善baseline特征

(1)增加构建买二卖二、买三卖三、买四卖四相关特征

# 计算加权平均价格(wap)以及相关特征
train_df['wap2'] = (train_df['n_bid2'] * train_df['n_bsize2'] + train_df['n_ask2'] * train_df['n_asize2']) / (train_df['n_bsize2'] + train_df['n_asize2'])
train_df['wap3'] = (train_df['n_bid3'] * train_df['n_bsize3'] + train_df['n_ask3'] * train_df['n_asize3']) / (train_df['n_bsize3'] + train_df['n_asize3'])
train_df['wap4'] = (train_df['n_bid4'] * train_df['n_bsize4'] + train_df['n_ask4'] * train_df['n_asize4']) / (train_df['n_bsize4'] + train_df['n_asize4'])

# 计算价格差异百分比(price spread)以及相关特征
train_df['price_spread_2'] = (train_df['n_ask2'] - train_df['n_bid2']) / ((train_df['n_ask2'] + train_df['n_bid2']) / 2)
train_df['price_spread_3'] = (train_df['n_ask3'] - train_df['n_bid3']) / ((train_df['n_ask3'] + train_df['n_bid3']) / 2)
train_df['price_spread_4'] = (train_df['n_ask4'] - train_df['n_bid4']) / ((train_df['n_ask4'] + train_df['n_bid4']) / 2)

# 当前时间特征
# 围绕买卖价格和买卖量进行构建
train_df['wap_balance_23'] = abs(train_df['wap2'] - train_df['wap3'])  # 加权平均价格差异
train_df['bid_spread_23'] = train_df['n_bid2'] - train_df['n_bid3']  # 买入价差
train_df['ask_spread_23'] = train_df['n_ask2'] - train_df['n_ask3']  # 卖出价差
train_df['total_volume_23'] = (train_df['n_asize2'] + train_df['n_asize3']) + (train_df['n_bsize2'] + train_df['n_bsize3'])  # 总交易量
train_df['volume_imbalance_23'] = abs((train_df['n_asize2'] + train_df['n_asize3']) - (train_df['n_bsize2'] + train_df['n_bsize3']))  # 交易量差异

# 围绕买卖价格和买卖量进行构建
# 对于 train_df
train_df['wap_balance_34'] = abs(train_df['wap3'] - train_df['wap4'])  # 加权平均价格差异
train_df['bid_spread_34'] = train_df['n_bid3'] - train_df['n_bid4']  # 买入价差
train_df['ask_spread_34'] = train_df['n_ask3'] - train_df['n_ask4']  # 卖出价差
train_df['total_volume_34'] = (train_df['n_asize3'] + train_df['n_asize4']) + (train_df['n_bsize3'] + train_df['n_bsize4'])  # 总交易量
train_df['volume_imbalance_34'] = abs((train_df['n_asize3'] + train_df['n_asize4']) - (train_df['n_bsize3'] + train_df['n_bsize4']))  # 交易量差异

        可以看到这里我只构建了二、三、四价的特征信息,而并没有构建五价的信息,我尝试了一下在构建相关特征信息之后线下训练直接过拟合了(达到了0.9+),可能和预测的label5有关,故在此处就不建议放入五价的更多信息。

(2)增加二、三、四价的平移、差分、窗口统计特征

# 历史平移
# 获取历史信息
for val in ['wap2','wap3','wap_balance_23','price_spread_2','bid_spread_23','ask_spread_23','total_volume_23','volume_imbalance_23']:
    for loc in [1,5,10,20,40,60]:
        train_df[f'file_{val}_shift{loc}'] = train_df.groupby(['file'])[val].shift(loc)
        test_df[f'file_{val}_shift{loc}'] = test_df.groupby(['file'])[val].shift(loc)
    
# 差分特征
# 获取与历史数据的增长关系
for val in ['wap2','wap3','wap_balance_23','price_spread_2','bid_spread_23','ask_spread_23','total_volume_23','volume_imbalance_23']:
    for loc in [1,5,10,20,40,60]:
        train_df[f'file_{val}_diff{loc}'] = train_df.groupby(['file'])[val].diff(loc)
        test_df[f'file_{val}_diff{loc}'] = test_df.groupby(['file'])[val].diff(loc)
    
# 窗口统计
# 获取历史信息分布变化信息
# 可以尝试更多窗口大小已经统计方式,如min、max、median等
for val in ['wap2','wap3','wap_balance_23','price_spread_2','bid_spread_23','ask_spread_23','total_volume_23','volume_imbalance_23']:
    train_df[f'file_{val}_win7_mean'] = train_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=7, min_periods=3).mean())
    train_df[f'file_{val}_win7_std'] = train_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=7, min_periods=3).std())
    
    test_df[f'file_{val}_win7_mean'] = test_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=7, min_periods=3).mean())
    test_df[f'file_{val}_win7_std'] = test_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=7, min_periods=3).std())

         因代码过多故只展示加入的二价信息,后面三价、四价信息一样。

2. 增加时间信息统计

       观察数据可以看到一共用户(uuid)含有多条会话,因此可以根据uuid进行分组进行统计数值型的特征信息。

        通过计算描述性统计指标来为数据集中的数值列生成新的特征

        首先,通过定义一个包含数值列名称的列表,确定了需要进行统计的特征。

        然后,对于每个唯一的'uuid'标识,代码迭代地组合每个数值列和'uuid',然后针对这些组合,在原始数据集中进行分组。

        接下来,通过计算这些分组内数值列的描述性统计指标,例如均值、标准差、最小值、中位数等,来得出有关这些数值列分布和特征的信息。

        最后,将计算得到的统计特征合并回原始数据集,以丰富数据的特征表示,为后续的建模分析提供更多有价值的信息。

# 定义需要进行描述性统计的数值列
num_cols = [['wap1', 'wap2', 'wap3', 'wap4',
            'price_spread', 'price_spread_2', 'price_spread_3', 'price_spread_4',
            'wap_balance', 'bid_spread', 'ask_spread', 'total_volume', 'volume_imbalance']]

# 针对每个 'uuid' 进行统计特征的计算
b = ['uuid']
for i in b:
    global_dense_group_feature = []
    
    # 构建特征组合列表,包含 'uuid' 和 num_cols 中的每个数值列
    for j in num_cols:
        global_dense_group_feature.append([i, j])

    # 对于每个 [key, value] 组合,进行统计特征的计算
    for [key, value] in tqdm(global_dense_group_feature):
        # 对数据按 'uuid' 分组,计算描述性统计指标,并重新命名列
        tmp = train_df.groupby([key])[value].describe().reset_index()
        tmp.columns = [key] + [key + '_' + value + '_' + x for x in ['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max']]
        
        # 将计算得到的统计特征合并回原始数据集中
        train_df = train_df.merge(tmp[[key] + [key + '_' + value + '_' + x for x in ['mean', 'std', 'min', '25%', '50%', '75%', 'max']]], on=key, how='left')

 3. 增加更多的窗口滑窗以及统计信息

        计算在不同时间窗口内的一些统计量,包括均值、标准差、中位数、最小值、最大值、百分位数(例如25%和75%分位数),以及移动平均线(例如指数加权移动平均)

        这些统计量是在每个文件组内进行计算,通过滚动窗口或指数加权移动平均的方式,考虑了最近的数据点,并将计算结果添加到原始DataFrame中,以补充原始特征数据。

        这些可以帮助分析数据的趋势、波动性和分布情况,为进一步的数据分析和建模提供更多信息。

for val in fea_cols:
    for time in [3, 10, 20]:
        # 均值
        train_df[f'file_{val}_win{time}_mean'] = train_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=time, min_periods=3).mean())
        # 标准差
        train_df[f'file_{val}_win{time}_std'] = train_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=time, min_periods=3).std()) 
        # 中位数
        train_df[f'file_{val}_win{time}_median'] = train_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=time, min_periods=3).median())
        # 最小值
        train_df[f'file_{val}_win{time}_min'] = train_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=time, min_periods=3).min())
        # 最大值
        train_df[f'file_{val}_win{time}_max'] = train_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=time, min_periods=3).max())
        # 25% 分位数
        train_df[f'file_{val}_win{time}_pct25'] = train_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=time, min_periods=3).quantile(0.25))
        # 75% 分位数
        train_df[f'file_{val}_win{time}_pct75'] = train_df.groupby(['file'])[val].transform(lambda x: x.rolling(window=time, min_periods=3).quantile(0.75))
        # 指数加权移动平均
        train_df[f'file_{val}_win{time}_ema'] = train_df.groupby(['file'])[val].transform(lambda x: x.ewm(span=time, min_periods=3).mean())
        

二、特征筛选方案

1. 相关性筛选特征

        检测列中是否包含具有相同值或缺失值过多的特征。对于具有唯一值数量为1的列,这些特征被认为在建模中没有意义

        检测相关系数矩阵中存在高于指定阈值的相关性的特征。通过计算数据的相关系数矩阵,代码遍历矩阵的每个元素,比较其绝对值与给定阈值。如果某个元素的绝对值大于阈值,就意味着相应的两个特征之间存在高相关性

print('过滤异常特征... ')
drop_cols = []  # 用于存储需要删除的异常特征列的列表
# 遍历DataFrame `df` 的每一列
for col in df.columns:
    # 如果列中的唯一值数量为1,说明该列中所有的值都相同,对于建模来说没有意义,将其添加到 `drop_cols` 列表中
    if df[col].nunique() == 1:
        drop_cols.append(col)
    # 计算每列缺失值的比例,如果缺失值比例超过总行数的 95%,也将该列添加到 `drop_cols` 列表中
    if df[col].isnull().sum() / df.shape[0] > 0.95:
        drop_cols.append(col)

print('过滤高相关特征...')
# 定义一个函数用于检测高相关特征
def correlation(data, threshold):
    col_corr = []  # 用于存储高相关特征列的列表
    corr_matrix = data.corr()  # 计算数据的相关系数矩阵
    # 遍历相关系数矩阵中的每个元素
    for i in range(len(corr_matrix)):
        for j in range(i):
            # 如果某个元素的绝对值大于阈值 `threshold`,说明这两个特征之间存在高相关性
            # 将其中一个特征的名称添加到 `col_corr` 列表中
            if abs(corr_matrix.iloc[i, j]) > threshold:
                colname = corr_matrix.columns[i]
                col_corr.append(colname)
    return list(set(col_corr))  # 返回包含所有高相关特征的列名的列表

2. 特征重要性筛选特征

        在特征选择的背景下,通过训练CatBoost分类器模型并分析特征重要性,确定哪些特征对于解决给定的分类问题最为重要。它将模型训练和特征选择结合在一起,以便找到对模型性能有显著贡献的特征,从而优化建模过程并提高预测的准确性


def model_train(x_train, y_train, x_test, y_test):
    params = {'learning_rate': 0.2, 'depth': 12, 'bootstrap_type':'Bernoulli','random_seed':2023,
                      'od_type': 'Iter', 'od_wait': 100, 'random_seed': 23, 'allow_writing_files': False,
                      'loss_function': 'MultiClass'}
    model = CatBoostClassifier(iterations=5000, **params)
    model.fit(x_train, y_train, eval_set=(x_test, y_test),
                metric_period=100,
                use_best_model=True, 
                cat_features=[],
                verbose=1)
    return model

def select_feature(train_df, feature_name, pred):
    # 数据划分
    x_train, x_test, y_train, y_test = train_test_split(train_df[feature_name], train_df[pred], test_size=0.25, random_state=23)
    # 将数据编号进行重编号
    x_train, y_train = x_train.reset_index(drop=True), y_train.reset_index(drop=True)
    x_test, y_test = x_test.reset_index(drop=True), y_test.reset_index(drop=True)
    cat_model = model_train(x_train, y_train, x_test, y_test)
    df = pd.DataFrame({'feature': x_train.columns, 'importance': cat_model.feature_importances_}).sort_values(
        by='importance', ascending=False)  # 降序
    use = df.loc[df['importance'] != 0, 'feature'].tolist()
    print('有用的特征个数:', len(use))
    # print('有用的特征:', use)
    return use

3.使用对抗训练筛选特征

         对抗训练在特征选择中是一种基于模型的方法,它通过在特征子集上构建对抗性模型,使得这些模型难以区分正常数据和噪声数据,从而筛选出对模型更具挑战性的特征。这样的方法可以鼓励模型学习更具鲁棒性的特征,同时抑制噪声对特征选择的影响

# 划分数据为特征和目标
X = train_df.drop(columns=['target'])
y = train_df['target']

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

# 使用 CatBoost 模型构建分类器
model = CatBoostClassifier(iterations=500, learning_rate=0.1, depth=8, random_seed=42)
model.fit(X_train, y_train, eval_set=(X_test, y_test), verbose=100)

# 提取特征重要性
feature_importances = model.get_feature_importance()

# 排序特征重要性
sorted_indices = np.argsort(feature_importances)[::-1]

# 选择前N个重要的特征
num_selected_features = 10
selected_feature_indices = sorted_indices[:num_selected_features]
selected_features = X.columns[selected_feature_indices]

print("Selected features:", selected_features)

4. feature-selection-with-null-importances

通过对数据的随机置换来构建一组基准分布,以评估每个特征在模型中的实际重要性

  • 首先,从 提供的数据集中读取数据,并进行预处理和准备。
  • 使用 CatBoost 模型构建一个基准模型,将原始数据拟合到模型中。
  • 通过对每个特征进行随机置换,对特征进行重要性评估。随机置换会破坏特征与目标之间的关系,从而产生一个“空”或“虚假”的特征重要性分布。
  • 计算原始特征与随机置换特征重要性之间的差异,以识别出真正对目标有贡献的特征。这些差异指示了模型在原始特征上的学习能力。
  • 结合原始特征重要性和虚假特征重要性分布,生成一个重要性置信度分数。较高的置信度分数表示特征对目标的贡献更加显著。
  • 基于特征的重要性置信度分数,筛选出最有价值的特征,用于进一步的建模和分析。

        通过这种基于空重要性的方法,该方案可以在特征选择过程中综合考虑特征与目标之间的关系以及模型的学习能力,从而识别出对于解决问题最为关键的特征,提高了模型的预测能力和可解释性。

实现方案链接

 Feature Selection with Null Importances | Kaggle

 三、内存压缩

        比赛按照上面的baseline会读取很大的数据内存,因此在此处放入一个降低内存的方法:

        通过减少数字列的数据类型并将对象列转换为分类类型来优化 DataFrame 'train_df' 的内存使用量,从而减少内存使用量。

# 定义一个列表,其中包含需要进行内存优化的特征列(排除 'uuid'、'time' 和 'file' 列)
predictor_columns = [col for col in test_df.columns if col not in ['uuid','time','file']]

# 定义内存优化函数,用于减少数据帧的内存使用量
def reduce_mem_usage(df):
    # 计算初始内存使用量
    start_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))
    
    # 遍历预测特征列
    for col in tqdm.tqdm(predictor_columns):
        col_type = df[col].dtype
        
        # 根据特征列的数据类型进行优化
        if col_type != object:
            c_min = df[col].min()
            c_max = df[col].max()
            
            # 根据数据范围选择适当的数据类型
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
        else:
            df[col] = df[col].astype('category')
    
    # 计算优化后的内存使用量
    end_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
    return df

# 调用内存优化函数,对训练数据帧进行内存优化
train_df = reduce_mem_usage(train_df)

四、验证方式

1. 交叉验证

        交叉验证是一种评估机器学习模型性能的技术,用于估计模型在未见过的数据上的表现。其基本思想是将原始数据集分成若干个子集(折),然后重复多次,每次将其中一折作为验证集,其余折作为训练集。这样可以对模型进行多次训练和验证,从而更全面地评估模型的性能。

在交叉验证过程中,每次迭代的步骤如下:

  • 将数据集分成k个子集,通常称为“折”(folds)。
  • 在每次迭代中,选择其中一个折作为验证集,其余折作为训练集。
  • 使用训练集训练模型,然后在验证集上进行预测,得到模型的性能指标。
  • 重复以上步骤k次,每次选择不同的验证集。
  • 计算k次迭代中性能指标的平均值,作为最终的模型性能评估。

常见的交叉验证方法包括 k 折交叉验证(k-Fold Cross Validation)、留一交叉验证(Leave-One-Out Cross Validation,LOOCV)以及随机分割交叉验证等。交叉验证可以帮助评估模型在不同数据子集上的泛化能力,降低过拟合的风险,提供对模型性能的更准确估计,以便更好地调整模型参数或选择最佳模型。

2. 时序验证

        时序验证是一种特殊的交叉验证方法,专门针对时间序列数据的模型评估。在时间序列数据中,数据点的顺序对于模型的训练和验证至关重要,因为未来的数据点可能受过去数据点的影响。时序验证方法能够在保留时间顺序的前提下,对时间序列数据进行模型评估,更好地模拟模型在实际应用中的性能。

        时序验证的基本思想是将时间序列数据划分为训练集和测试集,其中测试集的时间窗口在训练集之后。这样可以模拟模型在未来数据上的预测能力。常见的时序验证方法包括滚动窗口验证(Rolling Window Validation)和时间分割验证(Time-based Split Validation)等。

在滚动窗口验证中,训练集的时间窗口逐步向前滑动,每次增加一个时间步长,以便在不同时间段对模型进行训练和验证。在时间分割验证中,将时间序列数据按照时间顺序划分为多个时间段,每个时间段作为一个验证集,其之前的数据作为训练集。

五、模型集成

1. 多模型加权融合

        模型加权融合是一种集成学习方法,旨在通过将多个不同算法或同一算法的不同实例的预测结果进行加权组合,从而提高模型的预测性能和稳定性。在加权融合中,每个模型的权重根据其在训练集上的表现或其他评估指标而定,较优的模型获得更高的权重。这种方法能够平衡各个模型的优势,弥补单一模型的不足,从而在多个模型的共同作用下,产生更准确、鲁棒的预测结果。加权融合适用于提升预测效果、减小过拟合风险以及对多种算法进行有效组合的情境。

 2. stacking模型融合

        Stacking(又称为堆叠)是一种集成学习方法,用于将多个基本模型(也称为初级模型或基分类器)的预测结果作为输入,通过训练一个次级模型(也称为元模型或次级分类器)来生成最终的预测结果。Stacking 通过将不同模型的预测结果结合起来,可以有效地提高模型的预测性能和泛化能力。

 

from sklearn.model_selection import RepeatedKFold
def stack_model(oof_1, oof_2, oof_3, predictions_1, predictions_2, predictions_3, y):
    # 合并训练集的预测结果
    train_stack = pd.concat([oof_1, oof_2, oof_3], axis=1)
    # 合并测试集的预测结果
    test_stack = pd.concat([predictions_1, predictions_2, predictions_3], axis=1)
    # 初始化一个全零数组来存储最终的交叉验证预测结果
    oof = np.zeros((train_stack.shape[0],))
    # 初始化一个全零数组来存储最终的测试集预测结果
    predictions = np.zeros((test_stack.shape[0],))
    # 存储每个交叉验证折数的模型分数
    scores = []
    # 定义交叉验证折数和重复次数,用于后续交叉验证的划分
    folds = RepeatedKFold(n_splits=5, n_repeats=2, random_state=2021)
    for fold_, (trn_idx, val_idx) in enumerate(folds.split(train_stack, y)):
        print("第{}折交叉验证".format(fold_+1))
        # 获取当前折数的训练数据和标签
        trn_data, trn_y = train_stack.loc[trn_idx], y[trn_idx]
        # 获取当前折数的验证数据和标签
        val_data, val_y = train_stack.loc[val_idx], y[val_idx]
        # 初始化回归模型
        clf = Ridge(random_state=2021)
        # 在当前折数的训练数据上拟合模型
        clf.fit(trn_data, trn_y)
        # 对当前折数的验证数据进行预测
        oof[val_idx] = clf.predict(val_data)
        # 对测试集进行预测,并累加预测结果(最后会取平均值)
        predictions += clf.predict(test_stack) / (5 * 2)
        # 计算当前折数的验证集的ROC AUC得分
        score_single = roc_auc_score(val_y, oof[val_idx])
        # 将当前折数得分添加到scores列表中
        scores.append(score_single)
        print(f'{fold_+1}/5', score_single)
    # 输出交叉验证得分的平均值
    print('mena:', np.mean(scores))
    # 返回交叉验证预测结果和测试集预测结果
    return oof, predictions

 科大讯飞AI量化模型预测挑战赛_Baseline - 飞桨AI Studio (baidu.com)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux下安装nginx (tar解压版安装)

Linux下安装nginx (tar安装) 1、下载nginx 官方下载地址https://nginx.org/en/download.html 在这里插入图片描述 2.解压 解压‘nginx-1.16.1.tar.gz’到指定目录&#xff08;/usr/local/myWorkSpace&#xff09;并且重命名 命令&#xff1a; tar -xvf nginx-1.16.1.tar.gz …

共享式以太网的争用期

在以太网中&#xff0c;必然会发生碰撞。   站点从发送帧开始&#xff0c;最多经过 2 τ 2\tau 2τ就会检测到碰撞&#xff0c;此时 2 τ 2\tau 2τ被称为争用期或碰撞窗口。   站点从发送帧开始&#xff0c;经过争用期 2 τ 2\tau 2τ这段时间还没有检测到碰撞&#xff0c…

ModaHub魔搭社区——GPTCache是如何工作的?

在线服务通常表现出数据局部性,用户经常访问流行或趋势内容。缓存系统通过存储通常访问的数据来利用这种行为,这反过来减少了数据检索时间,提高了响应时间,并减轻了后端服务器的负担。传统缓存系统通常利用新查询和缓存查询之间的精确匹配来确定请求的内容在获取数据之前是…

LeetCode 31题:下一个排列

目录 题目 思路 代码 题目 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序…

网络安全(黑客)工作篇

一、网络安全行业的就业前景如何&#xff1f; 网络安全行业的就业前景非常广阔和有吸引力。随着数字化、云计算、物联网和人工智能等技术的迅速发展&#xff0c;网络安全的需求持续增长。以下是网络安全行业就业前景的一些关键因素&#xff1a; 高需求&#xff1a;随着互联网的…

MFC第二十七天 通过动态链表实现游戏角色动态增加、WM_ERASEBKGND背景刷新的原理、RegisterClass注册窗口与框架程序开发

文章目录 通过动态链表实现游戏角色动态增加CMemoryDC.hCFlashDlg.hCFlashDlg.cpp WM_ERASEBKGND背景刷新的原理RegisterClass注册窗口与框架程序开发CFrameRegister 通过动态链表实现游戏角色动态增加 CMemoryDC.h #pragma once#include "resource.h"/*内存DC类简介…

即将发布的 Kibana 版本可运行 Node.js 18

作者&#xff1a;Thomas Watson Kibana 构建在 Node.js 框架之上。 为了确保每个 Kibana 版本的稳定性和使用寿命&#xff0c;我们始终将捆绑的 Node.js 二进制文件保持为最新的最新长期支持 (LTS) 版本。 当 Node.js 版本 18 升级到 LTS 时&#xff0c;我们开始将 Kibana 升级…

图的遍历之 深度优先搜索和广度优先搜索

深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search)&#xff0c;和树的先序遍历比较类似。 它的思想&#xff1a;假设初始状态是图中所有顶点均未被访问&#xff0c;则从某个顶点v出发&#xff0c;首先访问该顶点&#xff0c;然后依次从它的各…

java中try-with-resources自动关闭io流

文章目录 java中try-with-resources自动关闭io流0 简要说明try-with-resources java中try-with-resources自动关闭io流 0 简要说明 在传统的输入输出流处理中&#xff0c;我们一般使用的结构如下所示&#xff0c;使用try - catch - finally结构捕获相关异常&#xff0c;最后不…

【Spring】如果你需要使用重试机制,请使用Spring官方的Spring Retry

文章目录 前言Spring Retry的基本使用第一步&#xff0c;引入Spring Retry的jar包第二步&#xff0c;构建一个RetryTemplate类第三步&#xff0c;使用RETRY_TEMPLATE注意事项 拓展方法降级操作重试策略&#xff1a;时间策略重试策略&#xff1a;指定异常策略 前言 Spring Retr…

吉利科技携手企企通,打造集团化数智供应链系统

近日&#xff0c;吉利科技集团有限公司&#xff08;以下简称“吉利科技”&#xff09;联合企企通成功召开SRM采购供应链管理项目启动会。企企通与吉利科技高层、项目负责人与团队成员出席此次启动会。 双方将携手在企业供应商全生命周期管理、采购全流程、电子招投标、采购分析…

opencv动态目标检测

文章目录 前言一、效果展示二、实现方法构造形态学操作所需的核:创建背景减除模型:形态学操作:轮廓检测: 三、代码python代码C代码 总结参考文档 前言 很久没更新文章了&#xff0c;这次因为工作场景需要检测动态目标&#xff0c;特此记录一下。 一、效果展示 二、实现方法 基…

华为运动健康,十年创新天地宽

我听一位朋友讲过这样一个故事。某天早上&#xff0c;急诊科的医生迎来了一位患者&#xff0c;患者进来后直接说&#xff1a;“大夫&#xff0c;我房颤了。” 这位医生非常诧异&#xff0c;因为心脏房颤确实非常危急&#xff0c;但很多时候并没有明显的生理体征&#xff0c;患者…

Flutter:屏幕适配

flutter_screenutil flutter_screenutil是一个用于在Flutter应用程序中进行屏幕适配的工具包。它旨在帮助开发者在不同屏幕尺寸和密度的设备上创建响应式的UI布局。 flutter_screenutil提供了一些用于处理尺寸和间距的方法&#xff0c;使得开发者可以根据设备的屏幕尺寸和密度…

基于Crow的C++的WebSocket服务器

基于Crow的C的WebSocket服务器 一、WebSocket 1.1 什么是WebSocket WebSocket 是一种持久化的通讯协议。 很多网站为了实现推送技术&#xff0c;所用的技术都是轮询&#xff0c;这种解决方案是指由浏览器每隔一段时间向服务器发出 HTTP 请求&#xff0c;然后服务器返回最新的…

React源码解析18(2)------ FilberNode,FilberRootNode结构关系

摘要 在上一篇&#xff0c;我们实现了通过JSX转换为ReactElement的方法&#xff0c;也看到了转换后React元素的结构。但是这个React元素&#xff0c;并不能很清楚的表达组件之间的关系&#xff0c;以及属性的处理。 所以在React内部&#xff0c;会将所有的React元素转换为Fil…

idea集成svn

一、注意 安装svn客户端的时候一定要勾选&#xff0c;否则在idea上集成svn的时候会找不到 svn.exe 而报错。 如果当初安装时忘记勾选&#xff0c;重新运行安装包&#xff0c;选择modify&#xff0c;勾选command line client tools项中的内容。 二、配置idea集成svn 三、检出(c…

电影票接单售票小程序搭建--java开源+后台管理系统

要搭建一个电影票接单售票小程序和后台管理系统&#xff0c;可以采取以下步骤&#xff08;以下步骤不分先后&#xff09;&#xff1a; 设计系统架构首先需要设计系统的整体架构&#xff0c;确定系统的技术选型、功能模块和业务流程等。可以考虑使用微服务架构&#xff0c;将系…

Jmeter添加cookie的两种方式

jmeter中添加cookie可以通过配置HTTP Cookie Manager&#xff0c;也可以通过HTTP Header Manager&#xff0c;因为cookie是放在头文件里发送的。 实例&#xff1a;博客园点击添加新随笔 https://i.cnblogs.com/EditPosts.aspx?opt1 如果未登录&#xff0c;跳转登录页&#xf…

MongoDB SQL

Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。C:\Users\Administrator>cd C:\MongoDB\Server\3.4\binC:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin>net start MongoDB 请求的…