三、特征工程
这里写目录标题
来源
Datewhle23期__数据挖掘心跳检测 :
https://github.com/datawhalechina/team-learning-data-mining/tree/master/HeartbeatClassification
作者:鱼佬、杜晓东、张晋、王皓月、牧小熊、姚昱君、杨梦迪
论坛地址:http://datawhale.club/t/topic/1574
import pandas as pd
import numpy as np
import tsfresh as tsf
from tsfresh import extract_features, select_features
from tsfresh.utilities.dataframe_functions import impute
1 特征工程
- 特征工程可以提高模型的上限,而特征处理是特征工程的核心部分,sklearn提供了较为完整的特征处理方法,包括数据预处理、特征选择、特征构造、归一化、标准化、one-hot编码、降维等。
图片来源 :https://www.jianshu.com/p/7066558bd386
2 载入数据及预处理
2.1 载入数据
path = 'C:/Users/GJX/Desktop/Datawhale-学习/23期/心电图/data/'
train = pd.read_csv(path+'train.csv')
test = pd.read_csv(path+'testA.csv')
train.head()
2.2 数据预处理
- 将心电信号拆开,并将宽表转长表
- 也可用pandas中
pivot_table
,melt
完成
# 对心电特征进行行转列处理,同时为每个心电信号加入时间步特征time
train_heartbeat_df = train["heartbeat_signals"].str.split(",", expand=True).stack()
train_heartbeat_df = train_heartbeat_df.reset_index()
train_heartbeat_df = train_heartbeat_df.set_index("level_0")
train_heartbeat_df.index.name = None
train_heartbeat_df.rename(columns={"level_1":"time", 0:"heartbeat_signals"}, inplace=True)
train_heartbeat_df["heartbeat_signals"] = train_heartbeat_df["heartbeat_signals"].astype(float)
train_heartbeat_df
# 将处理后的心电特征加入到训练数据中,同时将训练数据label列单独存储
train_label = train["label"]
train = train.drop("label", axis=1)
train = train.drop("heartbeat_signals", axis=1)
train = train.join(train_heartbeat_df) #连接训练集和处理后的df
train
pandas.DataFrame.join(other, on=None, how=’left’, lsuffix=”, rsuffix=”, sort=False)
-
other
:【DataFrame,或者带有名字的Series,或者DataFrame的list】如果传递的是
Series,那么其name属性应当是一个集合,并且该集合将会作为结果DataFrame的列名 -
on
:【列名称,或者列名称的list/tuple,或者类似形状的数组】连接的列,默认使用索引连接 -
how
:【{‘left’, ‘right’, ‘outer’, ‘inner’}
, default: ‘left’】连接的方式,默认为左连接 -
lsuffix
:【string】左DataFrame中重复列的后缀 -
rsuffix
:【string】右DataFrame中重复列的后缀 -
sort
:【boolean, default False】按照字典顺序对结果在连接键上排序。如果为False,连接键的顺序取决于连接类型(关键字)。
3 使用 tsfresh 进行时间序列特征处理
3.1 tsfresh
-
特征提取:
extract_features
-
特征过滤:过滤掉没有意义的值(NaN),保留有意义的特征;降维;
-
特征提取和过滤同时进行:
extract_relevant_features(timeseries, y, column_id='id', column_sort='time')
案例 :https://github.com/blue-yonder/tsfresh/tree/master/notebooks
3.2 特征提取
from tsfresh import extract_features
# 特征提取
train_features = extract_features(train, column_id='id', column_sort='time')
train_features
- 电脑带不动,以下为文档结果:
id sum_values abs_energy mean_abs_change mean_change ...
0 38.927945 18.216197 0.019894 -0.004859 ...
1 19.445634 7.705092 0.019952 -0.004762 ...
2 21.192974 9.140423 0.009863 -0.004902 ...
... ... ... ... ... ...
99997 40.897057 16.412857 0.019470 -0.004538 ...
99998 42.333303 14.281281 0.017032 -0.004902 ...
99999 53.290117 21.637471 0.021870 -0.004539 ...
100000 rows × 779 columns
3.3 特征选择
from tsfresh.utilities.dataframe_functions import impute
# 去除抽取特征中的NaN值
impute(train_features)
id sum_values abs_energy mean_abs_change mean_change ...
0 38.927945 18.216197 0.019894 -0.004859 ...
1 19.445634 7.705092 0.019952 -0.004762 ...
2 21.192974 9.140423 0.009863 -0.004902 ...
... ... ... ... ... ...
99997 40.897057 16.412857 0.019470 -0.004538 ...
99998 42.333303 14.281281 0.017032 -0.004902 ...
99999 53.290117 21.637471 0.021870 -0.004539 ...
100000 rows × 779 columns
- 接下来,按照特征和响应变量之间的相关性进行特征选择,这一过程包含两步:首先单独计算每个特征和响应变量之间的相关性,然后利用Benjamini-Yekutieli procedure进行特征选择,决定哪些特征可以被保留。
from tsfresh import select_features
# 按照特征和数据label之间的相关性进行特征选择
train_features_filtered = select_features(train_features, data_train_label)
train_features_filtered
id sum_values fft_coefficient__attr_"abs"__coeff_35 fft_coefficient__attr_"abs"__coeff_34 ...
0 38.927945 1.168685 0.982133 ...
1 19.445634 1.460752 1.924501 ...
2 21.192974 1.787166 2.1469872 ...
... ... ... ... ...
99997 40.897057 1.190514 0.674603 ...
99998 42.333303 1.237608 1.325212 ...
99999 53.290117 0.154759 2.921164 ...
100000 rows × 700 columns
可以看到经过特征选择,留下了700个特征。
参考资料
- https://www.jianshu.com/p/7066558bd386 特征工程介绍
- http://joyfulpandas.datawhale.club/Content/ch6.html pandas教程
- https://www.codetd.com/article/3219752 tsfresh