Task01 心跳信号分类赛题理解及baseline学习

赛题数据目的及评分体系

赛题数据

目的:心跳信号分类
数据:train.csv test A.csv
三个字段

FieldDescription
id为心跳信号分配的唯一标识
heartbeat_signals心跳信号序列
label心跳信号类别(0、1、2、3)

评测标准

本题

需要提交4种不同心跳信号预测的概率,选手提交结果与实际心跳类型结果进行对比,求预测的概率与真实值差值的绝对值(越小越好)。
具体计算公式如下:

针对某一个信号,若真实值为[y_1,y_2,y_3,y_4],模型预测概率值为[a_1,a_2,a_3,a_4],那么该模型的平均指标abs−sum为:
a b s − s u m = ∑ j = 1 n ∑ i = 1 4 ∣ y i − a i ∣ = {abs-sum={\mathop{ \sum }\limits_{{j=1}}^{{n}}{{\mathop{ \sum }\limits_{{i=1}}^{{4}}{{ \left| {y\mathop{{}}\nolimits_{{i}}-a\mathop{{}}\nolimits_{{i}}} \right| }}}}}}= abssum=j=1ni=14yiai=

例如,心跳信号为1,会通过编码转成[0,1,0,0][0,1,0,0],预测不同心跳信号概率为[0.1,0.7,0.1,0.1][0.1,0.7,0.1,0.1],那么这个预测结果的abs-sum为
a b s − s u m = ∣ 0.1 − 0 ∣ + ∣ 0.7 − 1 ∣ + ∣ 0.1 − 0 ∣ + ∣ 0.1 − 0 ∣ = 0.6 {abs-sum={ \left| {0.1-0} \right| }+{ \left| {0.7-1} \right| }+{ \left| {0.1-0} \right| }+{ \left| {0.1-0} \right| }=0.6} abssum=0.10+0.71+0.10+0.10=0.6

多分类算法常见的评估指标

  1. 混淆矩阵
  2. 准确率
    准确率是常用的一个评价指标,但是不适合样本不均衡的情况,医疗数据大部分都是样本不均衡数据。
    A c c u r a c y = C o r r e c t T o t a l   A c c u r a c y = T P + T N T P + T N + F P + F N Accuracy=\frac{Correct}{Total}\ Accuracy = \frac{TP + TN}{TP + TN + FP + FN} Accuracy=TotalCorrect Accuracy=TP+TN+FP+FNTP+TN

样本不均匀是什么意思?会在分类问题中出现。
不同类别的样本数量差距巨大

https://blog.csdn.net/zhongjunlang/article/details/79568601

  1. 精确率(Precision)也叫查准率简写为P
    精确率(Precision)是针对预测结果而言的,其含义是在被所有预测为正的样本中实际为正样本的概率在被所有预测为正的样本中实际为正样本的概率,精确率和准确率看上去有些类似,但是是两个完全不同的概念。精确率代表对正样本结果中的预测准确程度,准确率则代表整体的预测准确程度,包括正样本和负样本。
    P r e c i s i o n = T P T P + F P Precision = \frac{TP}{TP + FP} Precision=TP+FPTP

  2. 召回率(Recall) 也叫查全率 简写为R
    召回率(Recall)是针对原样本而言的,其含义是在实际为正的样本中被预测为正样本的概率
    R e c a l l = T P T P + F N Recall = \frac{TP}{TP + FN} Recall=TP+FNTP

  3. 宏查准率(macro-P)
    计算每个样本的精确率然后求平均值
    m a c r o P = 1 n ∑ 1 n p i {macroP=\frac{{1}}{{n}}{\mathop{ \sum }\limits_{{1}}^{{n}}{p\mathop{{}}\nolimits_{{i}}}}} macroP=n11npi

  4. 宏查全率(macro-R)
    计算每个样本的召回率然后求平均值
    m a c r o R = 1 n ∑ 1 n R i {macroR=\frac{{1}}{{n}}{\mathop{ \sum }\limits_{{1}}^{{n}}{R\mathop{{}}\nolimits_{{i}}}}} macroR=n11nRi

  5. 宏F1(macro-F1)
    m a c r o F 1 = 2 × m a c r o P × m a c r o R m a c r o P + m a c r o R {macroF1=\frac{{2 \times macroP \times macroR}}{{macroP+macroR}}} macroF1=macroP+macroR2×macroP×macroR 与上面的宏不同,微查准查全,先将多个混淆矩阵的TP,FP,TN,FN对应位置求平均,然后按照P和R的公式求得micro-P和micro-R,最后根据micro-P和micro-R求得micro-F1

  6. 微查准率(micro-P) m i c r o P = T P ‾ T P ‾ × F P ‾ {microP=\frac{{\overline{TP}}}{{\overline{TP} \times \overline{FP}}}} microP=TP×FPTP

  7. 微查全率(micro-R) m i c r o R = T P ‾ T P ‾ × F N ‾ {microR=\frac{{\overline{TP}}}{{\overline{TP} \times \overline{FN}}}} microR=TP×FNTP

  8. 微F1(micro-F1) m i c r o F 1 = 2 × m i c r o P × m i c r o R m i c r o P + m i c r o R {microF1=\frac{{2 \times microP\times microR }}{{microP+microR}}} microF1=microP+microR2×microP×microR

baseline方案

导入包

import os
import gc
import math

import pandas as pd
import numpy as np

import lightgbm as lgb
import xgboost as xgb
from catboost import CatBoostRegressor
from sklearn.linear_model import SGDRegressor, LinearRegression, Ridge
from sklearn.preprocessing import MinMaxScaler


from sklearn.model_selection import StratifiedKFold, KFold
from sklearn.metrics import log_loss
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder

from tqdm import tqdm
import matplotlib.pyplot as plt
import time
import warnings
warnings.filterwarnings('ignore')

读取数据

数据预处理

def reduce_mem_usage(df):
    start_mem = df.memory_usage().sum() / 1024**2 
    print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))
    
    for col in df.columns:
        col_type = df[col].dtype
        
        if col_type != object:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)  
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
        else:
            df[col] = df[col].astype('category')

    end_mem = df.memory_usage().sum() / 1024**2 
    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
    
    return df
# 简单预处理
train_list = []

for items in train.values:
    train_list.append([items[0]] + [float(i) for i in items[1].split(',')] + [items[2]])

train = pd.DataFrame(np.array(train_list))
train.columns = ['id'] + ['s_'+str(i) for i in range(len(train_list[0])-2)] + ['label']
train = reduce_mem_usage(train)

test_list=[]
for items in test.values:
    test_list.append([items[0]] + [float(i) for i in items[1].split(',')])

test = pd.DataFrame(np.array(test_list))
test.columns = ['id'] + ['s_'+str(i) for i in range(len(test_list[0])-1)]
test = reduce_mem_usage(test)

发现这些好像是一样的,有区别吗?
1

pd.DataFrame(train_list)
pd.DataFrame(np.array(train_list))

2

#i[1]加不加括号换成dataframe之后也一样
#这两个有什么区别吗?
for i in test.values:
    test_list.append([i[0]]+i[1].split(','))

for i in test.values:
    test_b.append([i[0]]+float(a) for a in i[1].split(','))

数据准备

x_train = train.drop(['id','label'], axis=1)
y_train = train['label']
x_test=test.drop(['id'], axis=1)

训练模型

#得分函数
def abs_sum(y_pre,y_tru):
    y_pre=np.array(y_pre)
    y_tru=np.array(y_tru)
    loss=sum(sum(abs(y_pre-y_tru)))
    return loss
def cv_model(clf, train_x, train_y, test_x, clf_name):
    folds = 5
    seed = 2021
    #分了五个,最后用了得分最高的那个
    kf = KFold(n_splits=folds, shuffle=True, random_state=seed)
    test = np.zeros((test_x.shape[0],4))

    cv_scores = []
    onehot_encoder = OneHotEncoder(sparse=False)
    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        print('************************************ {} ************************************'.format(str(i+1)))
        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]
        
        if clf_name == "lgb":
        #用Dataset放入数据
            train_matrix = clf.Dataset(trn_x, label=trn_y)
            valid_matrix = clf.Dataset(val_x, label=val_y)

            params = {
                'boosting_type': 'gbdt',
                'objective': 'multiclass',
                'num_class': 4,
                'num_leaves': 2 ** 5,
                'feature_fraction': 0.8,
                'bagging_fraction': 0.8,
                'bagging_freq': 4,
                'learning_rate': 0.1,
                'seed': seed,
                'nthread': 28,
                'n_jobs':24,
                'verbose': -1,
            }

            model = clf.train(params, 
                      train_set=train_matrix, 
                      valid_sets=valid_matrix, 
                      num_boost_round=2000, 
                      verbose_eval=100, 
                      early_stopping_rounds=200)
            val_pred = model.predict(val_x, num_iteration=model.best_iteration)
            test_pred = model.predict(test_x, num_iteration=model.best_iteration) 
            
        val_y=np.array(val_y).reshape(-1, 1)
        val_y = onehot_encoder.fit_transform(val_y)#为什么现在才用onehot??啊啊啊这个太晚了吧都训练完了??pred都算出来了
        print('预测的概率矩阵为:')
        print(test_pred)
        test += test_pred
        score=abs_sum(val_y, val_pred) #得分算法
        cv_scores.append(score)
        print(cv_scores)
    print("%s_scotrainre_list:" % clf_name, cv_scores)
    print("%s_score_mean:" % clf_name, np.mean(cv_scores))
    print("%s_score_std:" % clf_name, np.std(cv_scores))
    #这个也看不懂为什么要除?是有五个加起来了,但这个能直接除重??
    test=test/kf.n_splits

    return test
def lgb_model(x_train, y_train, x_test):
    lgb_test = cv_model(lgb, x_train, y_train, x_test, "lgb")
    return lgb_test
lgb_test = lgb_model(x_train, y_train, x_test)

KFold交叉验证

sklearn.model_selection.KFold(n_splits=3, shuffle=False, random_state=None)
思路:将训练/测试数据集划分n_splits个互斥子集,每次用其中一个子集当作验证集,剩下的n_splits-1个作为训练集,进行n_splits次训练和测试,得到n_splits个结果

参数说明:
n_splits:表示划分几等份
shuffle:在每次划分时,是否进行洗牌
①若为Falses时,其效果等同于random_state等于整数,每次划分的结果相同

②若为True时,每次划分的结果都不一样,表示经过洗牌,随机取样的random_state:随机种子数
属性:
①get_n_splits(X=None, y=None, groups=None):获取参数n_splits的值
②split(X,y=None, groups=None):将数据集划分成训练集和测试集,返回索引生成器
https://blog.csdn.net/kancy110/article/details/74910185

OneHot

lightGBM

LightGBM是个快速的,分布式的,高性能的基于决策树算法的梯度提升框架。可用于排序,分类,回归以及很多其他的机器学习任务中。

当我们提到集成学习时,肯定首先映入脑海的是bagging(装袋法)和boosting(提升法). bagging法包含许多独立模型的训练,最终通过某种形式的整合(平均,投票等)给出预测。装袋集成法的杰出代表是Random Forest.
相反,Boosting通过有序地训练模型,其中每个模型从先前模型的误差中学习。从弱模型开始,迭代地训练模型,每个模型添加到先前模型的预测以产生强大的总体预测。

在梯度提升决策树中,通过在相对于先前模型的叶节点的损失函数的误差残差计算的平均梯度的方向上应用梯度下降来找到序列模型。

LightGBM需要我们将数据置于LightGBM的Dataset对象中:
lgb_train = lgb.Dataset(X_train, y_train, free_raw_data=False)

lgb_val = lgb.Dataset(X_val, y_val, reference=lgb_train, free_raw_data=False)
LightGBM的核心参数定义:

core_params = {
    'boosting_type': 'gbdt', # rf, dart, goss
    'objective': 'binary', # regression, multiclass, binary
    'learning_rate': 0.05,
    'num_leaves': 31,
    'nthread': 4,
    'metric': 'auc' # binary_logloss, mse, mae
}

https://blog.csdn.net/liulunyang/article/details/87989315

预测结果

temp=pd.DataFrame(lgb_test)
result=pd.read_csv('sample_submit.csv')
result['label_0']=temp[0]
result['label_1']=temp[1]
result['label_2']=temp[2]
result['label_3']=temp[3]
result.to_csv('submit.csv',index=False)

提交

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值