工业蒸汽预测-06特征优化

赛题特征优化

1 导入数据

1
2
3
4
5
6
7
import pandas as pd

train_data_file = "./data/zhengqi_train.txt"
test_data_file = "./data/zhengqi_test.txt"

train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8')
test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8')

2 定义特征构造方法

定义特征构造方法

1
2
3
4
5
6
7
8
9
epsilon=1e-5

#组交叉特征,可以自行定义,如增加: x*x/y, log(x)/y 等等。
func_dict = {
'add': lambda x,y: x+y,
'mins': lambda x,y: x-y,
'div': lambda x,y: x/(y+epsilon),
'multi': lambda x,y: x*y
}

代码解释

epsilon 经常用作一个非常小的正数,用于避免在计算中出现除以零的情况。

该代码中的 epsilon 被用作分母在除法运算中的修正因子。当分母接近零时,加上一个非常小的正数 epsilon 可以确保避免出现除以零的错误,同时保持数值计算的准确性。

epsilon 被定义为 1e-5,即 0.00001。在执行诸如 div 函数的除法运算时,分母会加上 epsilon,从而避免除以零的情况。这样可以确保在进行组交叉特征计算时,不会出现除以零的错误,并保持计算的稳定性和准确性。

3 定义特征构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
def auto_features_make(train_data,test_data,func_dict,col_list):
train_data, test_data = train_data.copy(), test_data.copy()

for col_i in col_list:
for col_j in col_list:
for func_name, func in func_dict.items():
for data in [train_data,test_data]:
func_features = func(data[col_i],data[col_j])
col_func_features = '-'.join([col_i,func_name,col_j])
data[col_func_features] = func_features

return train_data,test_data

代码解释

函数的作用是在给定的数据集 train_datatest_data 上生成自动特征。

  1. 拷贝 train_datatest_data 数据集。

  2. 使用嵌套的循环 for col_i in col_list:for col_j in col_list: 遍历 col_list 中的每一对列名 col_icol_j,例如[V1 V0 ][V1 V1]

  3. 在内部的循环中,遍历 func_dict 中的每个函数,这些函数以函数名 func_name 和对应的函数对象 func 表示。

  4. 对于每个数据集(train_datatest_data),将 col_icol_j 列的值作为参数传递给当前迭代的函数 func,并计算得到新的特征值 func_features

  5. 创建一个新的特征列名 col_func_features,使用 - 连接 col_ifunc_namecol_j

  6. 将计算得到的新特征值 func_features 存储在对应的特征列 col_func_features 中。

  7. 重复步骤 4-6,直到遍历完所有的列和函数组合。

  8. 最后,返回生成新特征后的 train_datatest_data

对训练集和测试集数据进行特征构造

1
train_data2, test_data2 = auto_features_make(train_data,test_data,func_dict,col_list=test_data.columns)
D:\Development\anaconda3\envs\ml\lib\site-packages\ipykernel_launcher.py:10: PerformanceWarning: DataFrame is highly fragmented.  This is usually the result of calling `frame.insert` many times, which has poor performance.  Consider joining all columns at once using pd.concat(axis=1) instead.  To get a de-fragmented frame, use `newframe = frame.copy()`
  # Remove the CWD from sys.path while we load stuff.

代码解释

警告提示数据集可能存在严重的碎片化问题,即内存中的 DataFrame 对象非常分散。这通常是由于多次调用 DataFrame.insert 方法导致的,而 insert 方法的性能较差。

4 特征降维处理

1
2
3
4
5
6
7
8
9
10
11
12
from sklearn.decomposition import PCA   #主成分分析法

#PCA方法降维
pca = PCA(n_components=500)
# train_data2_pca = pca.fit_transform(train_data2.iloc[:,0:-1]) # 有误 target列并不在最后一列
train_data2_pca = pca.fit_transform(train_data2.drop(['target'], axis=1)) # 提取特征列
test_data2_pca = pca.transform(test_data2)

train_data2_pca = pd.DataFrame(train_data2_pca)
test_data2_pca = pd.DataFrame(test_data2_pca)

train_data2_pca['target'] = train_data2['target']
1
2
X_train2 = train_data2[test_data2.columns].values
y_train = train_data2['target']

5 模型训练和评估

使用lightgbm模型对新构造的特征进行模型训练和评估。注意运行时间长 二十多分钟。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# ls_validation i
from sklearn.model_selection import KFold
from sklearn.metrics import mean_squared_error
import lightgbm as lgb
import numpy as np

# 5折交叉验证
Folds=5
kf = KFold(n_splits=Folds, random_state=2019, shuffle=True)
# 记录训练和预测MSE
MSE_DICT = {
'train_mse':[],
'test_mse':[]
}

# 线下训练预测
for i, (train_index, test_index) in enumerate(kf.split(X_train2)):
# lgb树模型
lgb_reg = lgb.LGBMRegressor(
learning_rate=0.01,
max_depth=-1,
n_estimators=5000,
boosting_type='gbdt',
random_state=2019,
objective='regression',
)

# 切分训练集和预测集
X_train_KFold, X_test_KFold = X_train2[train_index], X_train2[test_index]
y_train_KFold, y_test_KFold = y_train[train_index], y_train[test_index]

# 训练模型
lgb_reg.fit(
X=X_train_KFold,y=y_train_KFold,
eval_set=[(X_train_KFold, y_train_KFold),(X_test_KFold, y_test_KFold)],
eval_names=['Train','Test'],
# early_stopping_rounds=100,# 已弃用
eval_metric='MSE',
# verbose=50 # 已弃用
callbacks=[lgb.log_evaluation(period=100), lgb.early_stopping(stopping_rounds=100)]
)


# 训练集预测 测试集预测
y_train_KFold_predict = lgb_reg.predict(X_train_KFold,num_iteration=lgb_reg.best_iteration_)
y_test_KFold_predict = lgb_reg.predict(X_test_KFold,num_iteration=lgb_reg.best_iteration_)

print('第{}折 训练和预测 训练MSE 预测MSE'.format(i))
train_mse = mean_squared_error(y_train_KFold_predict, y_train_KFold)
print('------\n', '训练MSE\n', train_mse, '\n------')
test_mse = mean_squared_error(y_test_KFold_predict, y_test_KFold)
print('------\n', '预测MSE\n', test_mse, '\n------\n')

MSE_DICT['train_mse'].append(train_mse)
MSE_DICT['test_mse'].append(test_mse)
print('------\n', '训练MSE\n', MSE_DICT['train_mse'], '\n', np.mean(MSE_DICT['train_mse']), '\n------')
print('------\n', '预测MSE\n', MSE_DICT['test_mse'], '\n', np.mean(MSE_DICT['test_mse']), '\n------')

将代码运行得到的5折交叉验证的各折叠训练MSE、预测MSE及平均MSE,与上一节中未做特征优化的结果对比,可以发现MSE得到进一步降低。


工业蒸汽预测-06特征优化
https://blog.966677.xyz/2023/09/15/工业蒸汽预测-06特征优化/
作者
Zhou1317fe5
发布于
2023年9月15日
许可协议