英特尔 oneAPI 2023 黑客松大赛:赛道二机器学习:预测淡水质量 实践分享

news2024/9/30 3:36:01

目录

  • 一、问题描述
  • 二、解决方案
    • 1、方案简述
    • 2、数据分析
      • 预处理
      • 特征类型处理
      • 特征分布分析
    • 3、特征构造
    • 4、特征选择
      • 过滤法
      • 重要性排序
    • 5、模型训练
  • 总结
  • 未来工作

一、问题描述

淡水是我们最重要和最稀缺的自然资源之一,仅占地球总水量的 3%。它几乎触及我们日常生活的方方面面,从饮用、游泳和沐浴到生产食物、电力和我们每天使用的产品。获得安全卫生的供水不仅对人类生活至关重要,而且对正在遭受干旱、污染和气温升高影响的周边生态系统的生存也至关重要。
比赛地址:英特尔 oneAPI 2023 黑客松大赛:赛道二机器学习:预测淡水质量

二、解决方案

1、方案简述

我们围绕赛道提供的数据集进行了多个特征间的相互交互,构造了一批与预测目标淡水质量相关的特征,并围绕特征与目标间的关联表现进行特征筛选,利用英特尔® Modin 分发版提升pandas处理特征集的效率,得到了49维相关特征作为最终的入模特证。最后,利用英特尔® 架构优化的XGBoost模型进行二分类,以此对淡水是否可以安全饮用而被依赖淡水的生态系统所使用进行预测。

2、数据分析

预处理

由于本赛道只有一份离线数据集,同时数据量级足够,我们在处理数据之前将该数据集按照5:2.5:2.5的比例划分为训练集、验证集、测试集。划分出测试集仅在模型推理阶段时使用,能够有效防止数据穿越等问题的发生,并能够准确对模型关于预测目标的拟合效果进行评估。

特征类型处理

1、特征类型划分为离散、连续两类特征

# 划分类别特征, 数值特征
cat_cols, float_cols = [], ['Target']
for col in data.columns:
    if data[col].value_counts().count() < 50:
        cat_cols.append(col)
    else:
        float_cols.append(col)
print('离散特征:', cat_cols)
print('连续特征:', float_cols)

离散特征: [‘Color’, ‘Source’, ‘Month’, ‘Day’, ‘Time of Day’, ‘Target’]
连续特征: [‘Target’, ‘pH’, ‘Iron’, ‘Nitrate’, ‘Chloride’, ‘Lead’, ‘Zinc’, ‘Turbidity’, ‘Fluoride’, ‘Copper’, ‘Odor’, ‘Sulfate’, ‘Conductivity’, ‘Chlorine’, ‘Manganese’, ‘Total Dissolved Solids’, ‘Water Temperature’, ‘Air Temperature’]

2、针对离散特征,进行缺失值处理

# 查看缺失值情况
display(data[cat_cols].isna().sum())
missing=data[cat_cols].isna().sum().sum()
print("\nThere are {:,.0f} missing values in the data.".format(missing))
print('-' * 50)

由于离散变量缺失比例都在1%左右,所以我们将缺失类别当作单独一类进行处理。

cateEnc_dict = {}
for col in cat_cols:
    if col == label_col:
        continue
    if str(data[col].dtype) == 'object':
        data[col] = data[col].fillna("#B")
    else:
        data[col] = data[col].fillna(-1000)
        data[col] = data[col].astype('int64')
    cate_set = sorted(set(data[col]))
    cateEnc_dict[col] = cate_set
    data[col] = data[col].replace(dict(zip(cate_set, range(1, len(cate_set) + 1))))

事实上,十二个月份属于有序类别特征,如果单纯地映射数字会破坏掉这种有序性,这里针对月份进行单独映射。

# 将月份映射至数字1~12
months = ["January", "February", "March", "April", "May",
          "June", "July", "August", "September", "October",
          "November", "December"]
data['Month'] = data['Month'].replace(dict(zip(months, range(1, len(months) + 1))))
display(data['Month'].value_counts())

针对明显无序的类别特征Color和Source,我们对其进行独特编码处理。对于有序类别特征,我们不对其进行额外处理。

# 将无序类别特征进行独热编码

color_ohe = OneHotEncoder()
source_ohe = OneHotEncoder()

X_color = color_ohe.fit_transform(data.Color.values.reshape(-1, 1)).toarray()
X_source = source_ohe.fit_transform(data.Source.values.reshape(-1, 1)).toarray()
pickle.dump(color_ohe, open('../feat_data/color_ohe.pkl', 'wb'))     # 将编码方式保存在本地
pickle.dump(source_ohe, open('../feat_data/source_ohe.pkl', 'wb'))   # 将编码方式保存在本地

dfOneHot = pandas.DataFrame(X_color, columns=["Color_" + str(int(i)) for i in range(X_color.shape[1])])
data = pandas.concat([data, dfOneHot], axis=1)

dfOneHot = pandas.DataFrame(X_source, columns=["Source_" + str(int(i)) for i in range(X_source.shape[1])])
data = pandas.concat([data, dfOneHot], axis=1)

由于连续变量缺失比例也都在2%左右,所以我们通过统计每个连续类别对应的中位数对缺失值进行填充。

display(data[float_cols].isna().sum())
missing=data[float_cols].isna().sum().sum()
print("\nThere are {:,.0f} missing values in the data.".format(missing))
# 使用中位数填充连续变量每列缺失值
fill_dict = {}
for column in list(data[float_cols].columns[data[float_cols].isnull().sum() > 0]):
    tmp_list = list(data[column].dropna())
    # 平均值
    mean_val = sum(tmp_list) / len(tmp_list)

    # 中位数
    tmp_list.sort()
    mid_val = tmp_list[len(tmp_list) // 2]
    if len(tmp_list) % 2 == 0:
        mid_val = (tmp_list[len(tmp_list) // 2 - 1] + tmp_list[len(tmp_list) // 2]) / 2

    fill_val = mid_val

    # 填充缺失值
    data[column] = data[column].fillna(fill_val)
    fill_dict[column] = fill_val

特征分布分析

# 针对每个连续变量的频率画直方图
data[float_cols].hist(bins=50,figsize=(16,12))

在这里插入图片描述
从上述直方图观察,有若干个变量的分布非常不规则,此处对它们进行非线性变换。

# 针对不规则分布的变量进行非线性变换,一般进行log
log_col = ['Iron', 'Zinc', 'Turbidity', 'Copper', 'Manganese']
show_col = []
for col in log_col:
    data[col + '_log'] = np.log(data[col])
    show_col.append(col + '_log')
    
# 特殊地,由于Lead变量0值占据了一定比例,此处特殊处理Lead变量
excep_col = ['Lead']
spec_val = {}
# 先将0元素替换为非0最小值,再进行log变换
for col in excep_col:
    spec_val[col] = data.loc[(data[col] != 0.0), col].min()
    data.loc[(data[col] == 0.0), col] = data.loc[(data[col] != 0.0), col].min()
    data[col + '_log'] = np.log(data[col])
    show_col.append(col + '_log')
    
data[show_col].hist(bins=50,figsize=(16,12))

在这里插入图片描述
可以发现,上述不规则分布的变量经过log之后已经变成了模型更容易拟合的类正态分布。

3、特征构造

由于特征之间往往隐藏着很多相关的信息等待挖掘,此处进行特征关联,得到新的特征。由于时间关系,此处我们仅以类别特征进行分组,去依次统计其余特征在组内的中位数、均值、方差、最大值、最小值、计数特征,挖掘有效的交互特征。

# 特征交互统计
cat_interaction_dict = {}
del_feat_list = []
if 'del_feat_list' in count_fea_dict:
    del_feat_list = count_fea_dict['del_feat_list']
add_feat_list = []
    
for cat_col1 in cat_cols:
    if cat_col1 == label_col:
        continue
    new_col = cat_col1 + '_count'
    if new_col not in data.columns and new_col not in del_feat_list:
        add_feat_list.append(new_col)
        temp = data.groupby(cat_col1).size()
        cat_interaction_dict[new_col] = dict(temp)
        temp = temp.reset_index().rename(columns={0: new_col})
        data = data.merge(temp, 'left', on=cat_col1)
    for cat_col2 in cat_cols:
        if cat_col2 == label_col:
            continue
        if cat_col1 == cat_col2:
            continue
        new_col = cat_col1 + '_' + cat_col2 + '_count'
        if new_col not in data.columns and new_col not in del_feat_list:
            add_feat_list.append(new_col)
            temp = data.groupby(cat_col1)[cat_col2].nunique()
            cat_interaction_dict[new_col] = dict(temp)
            temp = temp.reset_index().rename(columns={cat_col2: new_col})
            data = data.merge(temp, 'left', on=cat_col1)

for cat_col in cat_cols:
    if cat_col == label_col:
        continue
    for float_col in float_cols:
        if float_col == label_col:
            continue

        new_col = cat_col + '_' + float_col + '_mean'
        if new_col not in data.columns and new_col not in del_feat_list:
            add_feat_list.append(new_col)
            temp = data.groupby(cat_col)[float_col].mean()
            cat_interaction_dict[new_col] = dict(temp)
            temp = temp.reset_index().rename(columns={float_col: new_col})
            data = data.merge(temp, 'left', on=cat_col)

        new_col = cat_col + '_' + float_col + '_median'
        if new_col not in data.columns and new_col not in del_feat_list:
            add_feat_list.append(new_col)
            temp = data.groupby(cat_col)[float_col].median()
            cat_interaction_dict[new_col] = dict(temp)
            temp = temp.reset_index().rename(columns={float_col: new_col})
            data = data.merge(temp, 'left', on=cat_col)

        new_col = cat_col + '_' + float_col + '_max'
        if new_col not in data.columns and new_col not in del_feat_list:
            add_feat_list.append(new_col)
            temp = data.groupby(cat_col)[float_col].max()
            cat_interaction_dict[new_col] = dict(temp)
            temp = temp.reset_index().rename(columns={float_col: new_col})
            data = data.merge(temp, 'left', on=cat_col)

        new_col = cat_col + '_' + float_col + '_min'
        if new_col not in data.columns and new_col not in del_feat_list:
            add_feat_list.append(new_col)
            temp = data.groupby(cat_col)[float_col].min()
            cat_interaction_dict[new_col] = dict(temp)
            temp = temp.reset_index().rename(columns={float_col: new_col})
            data = data.merge(temp, 'left', on=cat_col)

        new_col = cat_col + '_' + float_col + '_std'
        if new_col not in data.columns and new_col not in del_feat_list:
            add_feat_list.append(new_col)
            temp = data.groupby(cat_col)[float_col].std()
            cat_interaction_dict[new_col] = dict(temp)
            temp = temp.reset_index().rename(columns={float_col: new_col})
            data = data.merge(temp, 'left', on=cat_col)

4、特征选择

过滤法

由于本次目标是对淡水质量是否可用进行二分类预测,所以我们针对包含构造特征的所有特征数据,对于离散特征,利用卡方检验判断特征与目标的相关性,对于连续特征,利用方差分析判断特征与目标的相关性,以此做特征集的第一轮筛选。

# 卡方检验对类别特征进行筛选
from  scipy.stats import chi2_contingency
import numpy as np
import pandas as pd

c_table = pd.crosstab(train[col], train['Target'], margins=True)
f_obs = np.array([c_table[0][0:2].values, c_table[1][0:2].values])
kt=chi2_contingency(f_obs)
print('卡方值=%.4f, p值=%.4f, 自由度=%i expected_frep=%s'%kt)
# 方差分析法对连续特征进行筛选
import statsmodels.api as sm
import pandas as pd
from statsmodels.formula.api import ols

df = pd.DataFrame({'ols_col':data[col], 'Target': data['Target']})
mod = ols('ols_col ~ Target', data=df).fit()        
ano_table = sm.stats.anova_lm(mod, typ=2)
print(ano_table)

重要性排序

针对第一轮筛选剩余的150维特征,使用模型去进行拟合,并根据最后模型产出的特征重要性从大到小排序,根据重要性以及设定阈值对特征进行第二轮筛选。

# 模型训练函数
def train(data):
    ## Prepare Train and Test datasets ##
    print("Preparing Train and Test datasets")
    X_train, X_test, y_train, y_test = prepare_train_test_data(data=data,
                                                               target_col='Target',
                                                               test_size=.25)
    
    ## Initialize XGBoost model ##
    ratio = float(np.sum(y_train == 0)) / np.sum(y_train == 1)
    parameters = {
        'scale_pos_weight': len(raw_data.loc[raw_data['Target'] == 0]) / len(raw_data.loc[raw_data['Target'] == 1]),
        'objective': "binary:logistic", 
        'learning_rate': 0.1,
        'n_estimators': 18,
        'max_depth': 10,
        'min_child_weight': 5,
        'alpha': 4,
        'seed': 1024,
    }
    xgb_model = XGBClassifier(**parameters)
    xgb_model.fit(X_train, y_train)

    print("Done!\nBest hyperparameters:", grid_search.best_params_)
    print("Best cross-validation accuracy: {:.2f}%".format(grid_search.best_score_ * 100))
    
    ## Convert XGB model to daal4py ##
    xgb = grid_search.best_estimator_
    daal_model = d4p.get_gbt_model_from_xgboost(xgb.get_booster())

    ## Calculate predictions ##
    daal_prob = d4p.gbt_classification_prediction(nClasses=2,
                                                  resultsToEvaluate="computeClassLabels|computeClassProbabilities",
                                                  fptype='float').compute(X_test,
                                                                          daal_model).probabilities  # or .predictions
    xgb_pred = pd.Series(np.where(daal_prob[:, 1] > .5, 1, 0), name='Target')
    xgb_acc = accuracy_score(y_test, xgb_pred)
    xgb_auc = roc_auc_score(y_test, daal_prob[:, 1])
    xgb_f1 = f1_score(y_test, xgb_pred)

    ## Plot model results ##
    print("\ndaal4py Test ACC: {:.2f}%, F1 Accuracy: {:.2f}%, AUC: {:.5f}".format(xgb_acc * 100, xgb_f1 * 100, xgb_auc))
    # plot_model_res(model_name='XGBoost', y_test=y_test, y_prob=daal_prob[:, 1])

    importance_df = pd.DataFrame({'importance':xgb.feature_importances_,'feat_name': data.drop('Target', axis=1).columns})
    importance_df = importance_df.sort_values(by='importance', ascending=False)
    
    return importance_df

importance_df = train(data)
display(importance_df.head())

针对现有的150维特征对XGB模型进行拟合,并针对输出的特征重要性得分进行排序,将小于阈值的特征进行过滤。
在这里插入图片描述

5、模型训练

针对经过两轮筛选得到的49维入模特征,使用RandomizedSearchCV对XGBoost的重要参数进行搜索,同时使用StratifiedKFold对模型效果进行交叉验证。

import modin.pandas as pd
from modin.config import Engine
Engine.put("dask")
# import pandas as pd

import os
import daal4py as d4p
from xgboost import XGBClassifier
import time
import warnings
import pandas
import json
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.colors
import plotly.io as pio
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from sklearn.preprocessing import OneHotEncoder

from sklearnex import patch_sklearn
patch_sklearn()

from sklearn.model_selection import train_test_split, StratifiedKFold, GridSearchCV, RandomizedSearchCV
from sklearn.preprocessing import RobustScaler, StandardScaler
from sklearn.metrics import make_scorer, recall_score, precision_score, accuracy_score, roc_auc_score, f1_score
from sklearn.metrics import roc_auc_score, roc_curve, auc, accuracy_score, f1_score
from sklearn.metrics import precision_recall_curve, average_precision_score
from sklearn.svm import SVC
from xgboost import plot_importance
import pickle

# 引入可视化函数

warnings.filterwarnings('ignore')
pio.renderers.default='notebook' # or 'iframe' or 'colab' or 'jupyterlab'
intel_pal, color=['#0071C5','#FCBB13'], ['#7AB5E1','#FCE7B2']

# # 以"layout"为key,后面实例为value创建一个字典
temp=dict(layout=go.Layout(font=dict(family="Franklin Gothic", size=12), height=500, width=1000))


def prepare_train_test_data(data, target_col, test_size):
    """
    Function to scale and split the data into training and test sets
    """
    scaler = StandardScaler()
    
    X = data.drop(target_col, axis=1)
    y = data[target_col]
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=21)

    # 按列归一化数据特征分布到 均值0方差1
    X_train_scaled = scaler.fit_transform(X_train)
    pickle.dump(scaler, open('../feat_data/scaler.pkl', 'wb'))  # 将编码方式保存在本地
    X_test_scaled = scaler.transform(X_test)
    print("Train Shape: {}".format(X_train_scaled.shape))
    print("Test Shape: {}".format(X_test_scaled.shape))

    return X_train_scaled, X_test_scaled, y_train, y_test


def plot_model_res(model_name, y_test, y_prob):
    """
    Function to plot ROC/PR Curves and predicted target distribution
    """

    intel_pal = ['#0071C5', '#FCBB13']
    color = ['#7AB5E1', '#FCE7B2']

    ## ROC & PR Curve ##
    fpr, tpr, _ = roc_curve(y_test, y_prob)
    roc_auc = auc(fpr, tpr)
    precision, recall, _ = precision_recall_curve(y_test, y_prob)
    auprc = average_precision_score(y_test, y_prob)

    fig = make_subplots(rows=1, cols=2,
                        shared_yaxes=True,
                        subplot_titles=['Receiver Operating Characteristic<br>(ROC) Curve',
                                        'Precision-Recall Curve<br>AUPRC = {:.3f}'.format(auprc)])
    # np.linspace等分0~1的区间为11份
    fig.add_trace(go.Scatter(x=np.linspace(0, 1, 11), y=np.linspace(0, 1, 11),
                             name='Baseline', mode='lines', legendgroup=1,
                             line=dict(color="Black", width=1, dash="dot")), row=1, col=1)
    fig.add_trace(go.Scatter(x=fpr, y=tpr, line=dict(color=intel_pal[0], width=3),
                             hovertemplate='True positive rate = %{y:.3f}, False positive rate = %{x:.3f}',
                             name='AUC = {:.4f}'.format(roc_auc), legendgroup=1), row=1, col=1)
    fig.add_trace(go.Scatter(x=recall, y=precision, line=dict(color=intel_pal[0], width=3),
                             hovertemplate='Precision = %{y:.3f}, Recall = %{x:.3f}',
                             name='AUPRC = {:.4f}'.format(auprc), showlegend=False), row=1, col=2)
    fig.update_layout(template=temp, title="{} ROC and Precision-Recall Curves".format(model_name),
                      hovermode="x unified", width=900, height=500,
                      xaxis1_title='False Positive Rate (1 - Specificity)',
                      yaxis1_title='True Positive Rate (Sensitivity)',
                      xaxis2_title='Recall (Sensitivity)', yaxis2_title='Precision (PPV)',
                      legend=dict(orientation='v', y=.07, x=.45, xanchor="right",
                                  bordercolor="black", borderwidth=.5))
    fig.show()

    ## Target Distribution ##
    plot_df = pd.DataFrame.from_dict({'State 0': (len(y_prob[y_prob <= 0.5]) / len(y_prob)) * 100,
                                      'State 1': (len(y_prob[y_prob > 0.5]) / len(y_prob)) * 100},
                                     orient='index', columns=['pct'])
    fig = go.Figure()
    fig.add_trace(go.Pie(labels=plot_df.index, values=plot_df.pct, hole=.45,
                         text=plot_df.index, sort=False, showlegend=False,
                         marker=dict(colors=color, line=dict(color=intel_pal, width=2.5)),
                         hovertemplate="%{label}: <b>%{value:.2f}%</b><extra></extra>"))
    fig.update_layout(template=temp, title='Predicted Target Distribution', width=700, height=450,
                      uniformtext_minsize=15, uniformtext_mode='hide')
    fig.show()

# 模型训练函数
def train(data):
    ## Prepare Train and Test datasets ##
    print("Preparing Train and Test datasets")
    X_train, X_test, y_train, y_test = prepare_train_test_data(data=data,
                                                               target_col='Target',
                                                               test_size=.25)
    
    ## Initialize XGBoost model ##
    ratio = float(np.sum(y_train == 0)) / np.sum(y_train == 1)
    parameters = {
        'scale_pos_weight': len(raw_data.loc[raw_data['Target'] == 0]) / len(raw_data.loc[raw_data['Target'] == 1]),
        'objective': "binary:logistic", 
        'learning_rate': 0.1,
        'n_estimators': 18,
        'max_depth': 10,
        'min_child_weight': 5,
        'alpha': 4,
        'seed': 1024,
    }
    xgb_model = XGBClassifier(**parameters)

    ## Tune hyperparameters ##
    strat_kfold = StratifiedKFold(n_splits=3, shuffle=True, random_state=21)
    print("\nTuning hyperparameters..")
    grid = {'min_child_weight': [1, 5, 10],
            'gamma': [0.5, 1, 1.5, 2, 5],
            'max_depth': [15, 17, 20],
            }

#     grid_search = RandomizedSearchCV(xgb_model, param_grid=grid,
#                                cv=strat_kfold, scoring=scorers,
#                                verbose=1, n_jobs=-1)
    
    strat_kfold = StratifiedKFold(n_splits=3, shuffle=True, random_state=1024)
    grid_search = RandomizedSearchCV(xgb_model, param_distributions=grid, 
                                    cv=strat_kfold, n_iter=10, scoring='accuracy', 
                                    verbose=1, n_jobs=-1, random_state=1024)
    grid_search.fit(X_train, y_train)

    print("Done!\nBest hyperparameters:", grid_search.best_params_)
    print("Best cross-validation accuracy: {:.2f}%".format(grid_search.best_score_ * 100))

    '''
    # normal predict ##
    xgb = grid_search.best_estimator_
    xgb_prob = xgb.predict_proba(X_test)[:, 1]
    xgb_pred = pd.Series(xgb.predict(X_test), name='Target')
    xgb_acc = accuracy_score(y_test, xgb_pred)
    xgb_auc = roc_auc_score(y_test, xgb_prob)
    xgb_f1 = f1_score(y_test, xgb_pred)

    print("\nTest ACC: {:.2f}%, F1 accuracy: {:.2f}%, AUC: {:.2f}%".format(xgb_acc * 100, xgb_f1 * 100, xgb_auc * 100))
    # print(xgb.feature_importances_)

    plot_model_res(model_name='XGB', y_test=y_test, y_prob=xgb_prob)
    '''
    
    ## Convert XGB model to daal4py ##
    xgb = grid_search.best_estimator_
    daal_model = d4p.get_gbt_model_from_xgboost(xgb.get_booster())

    ## Calculate predictions ##
    daal_prob = d4p.gbt_classification_prediction(nClasses=2,
                                                  resultsToEvaluate="computeClassLabels|computeClassProbabilities",
                                                  fptype='float').compute(X_test,
                                                                          daal_model).probabilities  # or .predictions
    xgb_pred = pd.Series(np.where(daal_prob[:, 1] > .5, 1, 0), name='Target')
    xgb_acc = accuracy_score(y_test, xgb_pred)
    xgb_auc = roc_auc_score(y_test, daal_prob[:, 1])
    xgb_f1 = f1_score(y_test, xgb_pred)

    ## Plot model results ##
    print("\ndaal4py Test ACC: {:.2f}%, F1 Accuracy: {:.2f}%, AUC: {:.5f}".format(xgb_acc * 100, xgb_f1 * 100, xgb_auc))
    # plot_model_res(model_name='XGBoost', y_test=y_test, y_prob=daal_prob[:, 1])

    ##
    importance_df = pd.DataFrame({'importance':xgb.feature_importances_,'feat_name': data.drop('Target', axis=1).columns})
    importance_df = importance_df.sort_values(by='importance', ascending=False)
    # pd.set_option('display.max_rows', None) #显示完整的行
    # display(importance_df.head())

    print('model saving...')
    pickle.dump(xgb, open("../result/model_best.dat", "wb"))
    
    return importance_df

训练得到最终模型后,对其进行保存,用于后续测试集的结果推理。

值得注意的一点是,针对测试集,需要根据训练集数据分布得到的统计值进行缺失值、独热编码等数据的处理,而非测试集数据分布下的统计值。最终,我们的模型在测试集上的ACC为89.04%。

总结

本项目在探索的过程中,先后经历了针对数据集进行精细化地特征分析、针对分析有效的数据特征进行特征交互,构建新的更有效的特征、针对特征工程后得到的408维特征,经过两轮特征选择得到49维高相关性特征,使用XGBoost进行模型训练,对最终模型进行多次拟合训练,得到了准确率在训练集表现88.76%,在验证集表现88.21%,在测试集表现89.04%的高准模型,同时在AUC评价下仍有很高的得分(测试集91.94%)。

未来工作

XGBoost虽然在训练阶段耗费不小的时间代价,但其在oneAPI提供的daal4py模型的加速下,其推理速度能得到更大的提升,随着数据量的增加,在保证训练机器足够的情况下,模型层面的准确率也会得到以进一步提升。

另外,我们的解决方案还有很大的提升空间,目前我们仅对少量的特征进行了分析以及交互处理,仍然有着很多潜在的与目标相关的信息等待着我们挖掘,相信在后续对本方案进行精细化探索后,仍然能够提升我们的模型性能。

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

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

相关文章

Python:pyecharts可视化

文章目录 简介Geo地理图绘制折线图区域突出显示横坐标带选择展示 add地图Mapformatter控制value显示在图中显示value值目标html的解析自定义地图js资源原生地图js的解析解决省份上文字不居中的问题 桑基图设置桑基柱的颜色 参考文献 简介 &#xff08;这是20年的笔记&#xff…

医疗陪诊小程序开发功能有哪些?

医疗陪诊系统开发功能有哪些&#xff1f; 1、注册登录。用户初次使用需使用个人手机号码或者是第三方社交账号进行注册登录&#xff0c;登陆之后填写个人相关信息&#xff0c;姓名、性别、年龄、过往病史、病历等信息&#xff0c;以便医生可以根据患者资料进行初步判断。…

小文智能自定义变量详解

在小文交互场景设计时&#xff0c;有一个特殊功能&#xff0c;叫做自定义变量。有时&#xff0c;根据外呼对象的不同&#xff0c;需要对用户传达不同的内容&#xff0c;比如称呼、地址、公司名称等等。此时&#xff0c;就可以使用小文交互的自定义变量功能来实现对不同用户呼出…

Destination unreachable(Port unreachable) 错误原因和解决办法

Destination unreachable(Port unreachable) 是一条由网络设备&#xff08;如路由器或防火墙&#xff09;生成的ICMP&#xff08;Internet Control Message Protocol&#xff09;错误消息&#xff0c;用于通知源设备目标设备或端口无法到达。 一、什么是ICMP ICMP&#xff08;I…

【中危】Guava<32.0.0 存在竞争条件漏洞

漏洞描述 Guava 是 Google 公司开发的开源 Java 代码库&#xff0c;提供常用的Java工具和数据结构。 Guava 1.0 至 31.1 版本中的 FileBackedOutputStream 类使用Java的默认临时目录创建文件&#xff0c;由于创建的文件名容易被攻击者猜测&#xff0c;在 Unix 和 Android Ice…

静电设备在静电处理环节中的原理

静电设备在静电处理环节中发挥着重要的作用。以下是一些常见的静电设备及其作用&#xff1a; 1. 静电消除器&#xff1a;静电消除器通过释放相等数量的正负离子&#xff0c;有效地中和周围环境中的静电荷&#xff0c;从而减少或消除静电引起的问题&#xff0c;例如静电吸附、电…

AI科技的应用革命:改变生活方式、提升人类生产力

人工智能技术的发展和应用&#xff0c;正在对我们的生活方式产生深远的影响。无论是在家庭、工作还是娱乐方面&#xff0c;越来越多的AI工具正在改变我们的习惯、观念和行为。它们为我们提供了更加智能化、个性化和定制化的服务和产品&#xff0c;让我们的生活变得更加便捷、高…

NXP i.MX 8M Plus工业核心板硬件说明书( 四核ARM Cortex-A53 + 单核ARM Cortex-M7,主频1.6GHz)

1 硬件资源 创龙科技SOM-TLIMX8MP是一款基于NXP i.MX 8M Plus的四核ARM Cortex-A53 单核ARM Cortex-M7异构多核处理器设计的高端工业核心板&#xff0c;ARM Cortex-A53(64-bit)主处理单元主频高达1.6GHz&#xff0c;ARM Cortex-M7实时处理单元主频高达800MHz。处理器…

【教程】Flutter与Rust完美交互,无需手写FFI代码

实践环境&#xff1a;Windows11 flutter_rust_bridge官方文档 Flutter环境配置教程 | Rust环境配置教程 新建一个全新的Flutter项目并运行&#xff1a; flutter create example && cd example && flutter run 在Flutter项目根目录新建一个Rust项目&#xf…

从0到1精通自动化,接口自动化测试——数据驱动DDT实战

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 DDT简介 名称&am…

FPGA解码 MIPI 视频 OV4689采集 4line 2.7K分辨率 提供工程源码和技术支持

目录 1、前言2、Xilinx官方主推的MIPI解码方案3、本 MIPI CSI2 模块性能及其优越性4、我这里已有的 MIPI 编解码方案5、vivado工程介绍5、上板调试验证6、福利&#xff1a;工程代码的获取 1、前言 FPGA图像采集领域目前协议最复杂、技术难度最高的应该就是MIPI协议了&#xff…

python spider 爬虫 之 解析 xpath 、jsonpath、BeautifulSoup (三)

BeautifulSoup 简称&#xff1a;bs4 BeautifulSoup跟lxml 一样&#xff0c;是一个html文档的解析器&#xff0c;主要功能也是解析和提取数据 优缺点 缺点&#xff1a;效率没有lxml的效率高 优点&#xff1a;接口接口人性化&#xff0c;使用方便 延用了css选择器 安装Beautifu…

故障处理程序框图原理

一、故障处理程序框图 故障处理程序包括保护软压板的投切检查、保护定值比较、保护逻辑判断、跳闸处理程序和后加速部分。故障处理程序框图如图2&#xff0d;8所示。保护逻辑判断程序将在第三章中详述。 进入故障处理程序入口&#xff0c;首先置标志位KST为1&#xff0c;驱动起…

传统表格还是思维导图?哪种基本功能测试用例模式更好?

这个问题先抛出我的观点&#xff1a; 具体选择哪种形式更好&#xff0c;需要根据具体情况来考虑。 如果测试用例较为简单&#xff0c;可以选择表格形式&#xff1b;如果测试用例较为复杂&#xff0c;可以选择思维导图形式。但实际工作中&#xff0c;二者一般是结合使用的。 …

php正则匹配

一、基础内容 1、通用原子 2、元字符 符号意义.除了换行以外的所有字符*匹配前面的内容出现 0 次及以上?匹配前面的内容出现 0 次或 1 次出现一次或多次$必须以它结尾{n}恰巧出现 n 次{n,}大于等于 n 次{n,m}大于等于n,小于等于 m[]是一个集合&#xff0c;匹配中括号中的任…

实时数据管理与生产控制:MES系统的作用和优势解析

一、什么是MES系统&#xff1f; MES系统&#xff0c;全称为制造执行系统&#xff08;Manufacturing Execution System&#xff09;&#xff0c;是一种用于管理和监控制造过程的信息系统。它通过实时收集、分析和共享生产数据&#xff0c;提供全面的生产计划、调度、追踪和报告…

jenkins选择不同构建环境

1、业务在有些情况下需要选择不同的环境来构建服务&#xff0c;使用同一套代码读取不同的配置 2、jenkins使用如下配置即可实现构建环境的选择 2.1、配置构建选项 2.2、配置构建tag 2.3、选择构建时间参数 3、使用如下pipeline实现jenkins构建环境选择 pipeline {agent any…

黑马程序员前端 Vue3 小兔鲜电商项目——(十二)会员中心

文章目录 路由配置模板代码会员中心个人信息用户订单 配置路由 个人中心信息渲染使用 Pinia 数据渲染个人信息 猜你喜欢封装接口渲染数据 我的订单基础列表渲染tab切换实现分页实现 细节优化默认三级路由设置订单状态显示适配 路由配置 模板代码 会员中心 创建 src\views\Me…

XR云新未来圆桌精彩回顾 | XR应用场景迭代下的新商业模式

6月15日&#xff0c;由平行云联合首都在线共同主办&#xff0c;中关村软件园协办&#xff0c;以“XR云新未来|弹性算力赋能可交互、沉浸式商业实践”为主题的XR行业交流盛会在北京成功举办。 本次会议我们邀请到平行云科技创始人兼CEO 李岩、XREAL 云XR负责人 吴维、瑞帆科技…

吃透JAVA的Stream流操作,多年实践总结

在JAVA中&#xff0c;涉及到对数组、Collection等集合类中的元素进行操作的时候&#xff0c;通常会通过循环的方式进行逐个处理&#xff0c;或者使用Stream的方式进行处理。 例如&#xff0c;现在有这么一个需求&#xff1a; 从给定句子中返回单词长度大于5的单词列表&#xf…