天池比赛数据挖掘心电图特征工程

黎明之道
• 阅读 1857

Task3 特征工程

3.1 学习目标

  • 学习时间序列数据的特征预处理方法
  • 学习时间序列特征处理工具 Tsfresh(TimeSeries Fresh)的使用

3.2 内容介绍

  • 数据预处理
    • 时间序列数据格式处理
    • 加入时间步特征time
  • 特征工程
    • 时间序列特征构造
    • 特征筛选
    • 使用 tsfresh 进行时间序列特征处理

3.3 代码示例

3.3.1 导入包并读取数据

# 包导入
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
# 数据读取
data_train = pd.read_csv("train.csv")
data_test_A = pd.read_csv("testA.csv")

print(data_train.shape)
print(data_test_A.shape)
(100000, 3)
(20000, 2)
data_train.head()
      id        heartbeat_signals                                    label
0        0            0.9912297987616655,0.9435330436439665,0.764677…        0.0
1        1            0.9714822034884503,0.9289687459588268,0.572932…        0.0
2        2            1.0,0.9591487564065292,0.7013782792997189,0.23…        2.0
3        3            0.9757952826275774,0.9340884687738161,0.659636…        0.0
4        4            0.0,0.055816398940721094,0.26129357194994196,0…        2.0
data_test_A.head()
        id        heartbeat_signals
0        100000    0.9915713654170097,1.0,0.6318163407681274,0.13…
1        100001    0.6075533139615096,0.5417083883163654,0.340694…
2        100002    0.9752726292239277,0.6710965234906665,0.686758…
3        100003    0.9956348033996116,0.9170249621481004,0.521096…
4        100004    1.0,0.8879490481178918,0.745564725322326,0.531…

3.3.2 数据预处理

# 对心电特征进行行转列处理,同时为每个心电信号加入时间步特征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)

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 × 2 columns
# 将处理后的心电特征加入到训练数据中,同时将训练数据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)

data_train
            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]
            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

可以看到,每个样本的心电特征都由205个时间步的心电信号组成。

3.3.3 使用 tsfresh 进行时间序列特征处理

  1. 特征抽取

Tsfresh(TimeSeries Fresh)是一个Python第三方工具包。 它可以自动计算大量的时间序列数据的特征。此外,该包还包含了特征重要性评估、特征选择的方法,因此,不管是基于时序数据的分类问题还是回归问题,tsfresh都会是特征提取一个不错的选择。官方文档:Introduction — tsfresh 0.17.1.dev24+g860c4e1 documentation

from tsfresh import extract_features

# 特征提取
train_features = extract_features(data_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
  1. 特征选择 train_features中包含了heartbeat_signals的779种常见的时间序列特征(所有这些特征的解释可以去看官方文档),这其中有的特征可能为NaN值(产生原因为当前数据不支持此类特征的计算),使用以下方式去除NaN值:
    from tsfresh.utilities.dataframe_functions import impute
    

去除抽取特征中的NaN值

impute(train_features)


```python
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 [1] 进行特征选择,决定哪些特征可以被保留。

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个特征。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Karen110 Karen110
3年前
​一篇文章总结一下Python库中关于时间的常见操作
前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
3年前
Prometheus监控学习笔记之PromQL简单示例
0x00简单的时间序列选择返回度量指标http_requests_total的所有时间序列样本数据:http_requests_total返回度量指标名称为http_requests_total,标签分别是job"apiserver",handler"/api/comments"
Wesley13 Wesley13
3年前
4cast
4castpackageloadcsv.KumarAwanish发布:2020122117:43:04.501348作者:KumarAwanish作者邮箱:awanish00@gmail.com首页:
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Stella981 Stella981
3年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_