数据挖掘HeartbeatClassification——特征工程

这一部分所要讲的是,将收集到的数据进行专项处理,得到一个合理的数据格式,我们后面所要用的模型便能利用这样的数据,通过机器学习的方式进行数学建模。如此一来,挖掘到的数据就变得有价值了,通过这些数字表象找到了背后的意义。本项目是处理的是患者的心跳信号,意义便是建立起来的模型可以对某些病症进行检测。

1.数据预处理

对心电特征进行行转列处理,同时为每个心电信号加入时间步特征time

train_heartbeat_df = data_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)
print(train_heartbeat_df)

简单分析一下以上的代码,主要利用pandas的一些处理方法:reset_index(),set_index()

1.1分离再组合

未进行处理以前的"heartbeat_signals"——
在这里插入图片描述

train_heartbeat_df = data_train["heartbeat_signals"].str.split(",", expand=True).stack()
print(train_heartbeat_df)

找到训练数据中"heartbeat_signals"中所对应的列数据,并利用split()函数以“ , ”,将每一行的数据分开,再利用stack()函数在axis=0这个维度对数据进行堆叠。对stack()的理解可以品读一下这位博主的见解——stack()的理解与使用
处理结果:

0      0      0.9912297987616655
       1      0.9435330436439665
       2      0.7646772997256593
       3      0.6185708990212999
       4      0.3796321642826237
                     ...        
99999  200                   0.0
       201                   0.0
       202                   0.0
       203                   0.0
       204                   0.0
Length: 20500000, dtype: object

1.2 重置索引

这一部分将会使用reset_index()函数,我们可以通过这位博主简单的了解它的作用和使用方法——reset_index()的使用讲解

train_heartbeat_df = data_train["heartbeat_signals"].str.split(",", expand=True).stack()
train_heartbeat_df = train_heartbeat_df.reset_index()
print(train_heartbeat_df)
             level_0  level_1                   0
0               0        0         0.9912297987616655
1               0        1         0.9435330436439665
2               0        2         0.7646772997256593
3               0        3         0.6185708990212999
4               0        4         0.3796321642826237
...           ...      ...                 ...
20499995    99999      200                 0.0
20499996    99999      201                 0.0
20499997    99999      202                 0.0
20499998    99999      203                 0.0
20499999    99999      204                 0.0

[20500000 rows x 3 columns]

1.3 弃用原有索引

将心跳信号的“level_0”所在列的数据作为新的索引,并弃用原有的索引。

 train_heartbeat_df = data_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")
 print(train_heartbeat_df)
level_0        level_1          0               
0              0          0.9912297987616655
0              1          0.9435330436439665
0              2          0.7646772997256593
0              3          0.6185708990212999
0              4          0.3796321642826237
...          ...                 ...
99999        200                 0.0
99999        201                 0.0
99999        202                 0.0
99999        203                 0.0
99999        204                 0.0

[20500000 rows x 2 columns]

1.4 改名

进行列名的更改,并对原表也进行相同的变动(1.3中打印的列名)

train_heartbeat_df = data_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
# inplace=True 表示该处理将会对原表也进行相应的处理;FALSE便是不对原表进行变动
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)
print(train_heartbeat_df)
        time        heartbeat_signals
0         0           0.991230
0         1           0.943533
0         2           0.764677
0         3           0.618571
0         4           0.379632
...     ...                ...
99999   200           0.000000
99999   201           0.000000
99999   202           0.000000
99999   203           0.000000
99999   204           0.000000

[20500000 rows x 2 columns]

1.5 心跳信号改后回填训练集

将处理后的心电特征加入到训练数据中,同时将训练数据label列单独存储。

data_train_label = data_train["label"]
data_train = data_train.drop("label", axis=1)
data_train = data_train.drop("heartbeat_signals", axis=1)
data_train = data_train.join(train_heartbeat_df)
print(train_heartbeat_df)

需要注意一下,这里显示的只是数据首尾的五个数据值,为ID=0 的前五个值和ID=9999 的后五个值

            id		  time	       heartbeat_signals
0			0			0			0.991230
0			0			1			0.943533
0			0			2			0.764677
0			0			3			0.618571
0			0			4			0.379632
...		    ...		    ...		      ...
99999		99999		200		      0.0
99999		99999		201		      0.0
99999		99999		202		      0.0
99999		99999		203			  0.0
99999		99999		204			  0.0

20500000 rows × 4 columns
data_train[data_train["id"]==1]

这里显示了某位就医者的心跳信号,共205个信号值

			id		  time		heartbeat_signals
1			1			0			0.971482
1			1			1			0.928969
1			1			2			0.572933
1			1			3			0.178457
1			1			4			0.122962
...			...			...			...
1			1			200			0.0
1			1			201			0.0
1			1			202			0.0
1			1			203			0.0
1			1			204			0.0

205 rows × 4 columns

2. tsfresh——时间序列特征处理

tsfresh可以自动计算大量的时间序列数据的特征,所谓的特征,即这些特征描述了时间序列的基本特征,如峰数、平均值或最大值或更复杂的特征,如时间反转对称统计。同时通过假设检验来将特征消减到最能解释趋势的特征,称为去相关性。然后,可以使用这些特征集在时间序列上构造统计或机器学习模型,例如在回归或分类任务中使用————引用知乎博主

2.1 pip安装

pip install tsfresh

2.2 特征处理

利用tsfresh包中的extract_features()函数对时间序列数据进行处理。

注意,该过程需要大内存以及好的计算性能来支撑。本人16g内存,在对原数据不进行压缩处理的情况下,内存瞬间占满爆炸,然后报错。

from tsfresh import extract_features
# 特征提取
train_features = extract_features(data_train, column_id='id', column_sort='time')
print(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

2.3 去掉处理过程中的NaN值

NaN可能为当前数据不支持此类特征的计算,所以在自动提取的过程中被置为了NaN值。

from tsfresh.utilities.dataframe_functions import impute
# 去除抽取特征中的NaN值
print(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

2.4 特征选择

该过程是按照特征和响应变量之间的相关性进行特征选择,这一过程包含两步:首先单独计算每个特征和响应变量之间的相关性,然后利用Benjamini-Yekutieli procedure(如下) 进行特征选择,决定哪些特征可以被保留。

Benjamini, Y. and Yekutieli, D. (2001). The control of the false discovery rate in multiple testing under dependency. Annals of statistics, 1165–1188

from tsfresh import select_features
# 按照特征和数据label之间的相关性进行特征选择
train_features_filtered = select_features(train_features, data_train_label)
prin(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

请注意 数据的shape,779列经过处理后留下了700列数据特征

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值