財務リスク管理タスク 3 - 機能エンジニアリング

学習目標

  • 特徴前処理、欠損値、外れ値処理、データ バケット化などの特徴処理方法を学習します。
  • 機能のインタラクション、エンコード、選択に対応する方法を学習します。

序章

  • データの前処理:
  • 欠損値の補充
  • 時刻フォーマットの処理
  • オブジェクトタイプの特性を値に変換
  • 外れ値の処理:
  • 3segama原則に基づいて
  • 箱ひげ図に基づく
  • データビニング:
  • 固定幅のビニング
  • 分位数分箱
  • 離散数値データのビニング
  • 連続数値データビニング
  • カイ二乗ビニング
  • 機能のインタラクション:
  • 機能と機能の組み合わせ
  • 特徴と特徴の間の導出
  • 特徴導出に関するその他の試み
  • 特徴エンコード:
  • ワンホットエンコーディング
  • ラベルエンコードエンコーディング
  • 機能の選択:
  • フィルター
  • ラッパー
  • 埋め込み

コード例

パッケージをインポートしてデータを読み取る

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
from tqdm import tqdm
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
from sklearn.preprocessing import MinMaxScaler
import xgboost as xgb
import lightgbm as lgb
from catboost import CatBoostRegressor
import warnings
from sklearn.model_selection import StratifiedKFold, KFold
from sklearn.metrics import accuracy_score, f1_score, roc_auc_score, log_loss
warnings.filterwarnings('ignore')
train = pd.read_csv('./data/train.csv')
testA = pd.read_csv('./data/testA.csv')

特徴の前処理

numerical_fea = list(train.select_dtypes(exclude=['object']).columns)
category_fea = list(filter(lambda x: x not in numerical_fea,list(train.columns)))
label = 'isDefault'
numerical_fea.remove(label)
欠損値の穴埋め
# 查看缺失值
train.isnull().sum()

ここに画像の説明を挿入

# 按照平均数填充数值特征
train[numerical_fea] = train[numerical_fea].fillna(train[numerical_fea].median())
testA[numerical_fea] = testA[numerical_fea].fillna(train[numerical_fea].median())

# #按照众数填充类别型特征
train[category_fea] = train[category_fea].fillna(train[category_fea].mode())
testA[category_fea] = testA[category_fea].fillna(train[category_fea].mode())
train.isnull().sum()

ここに画像の説明を挿入

時刻フォーマットの処理

for data in [train, testA]:
    data['issueDate'] = pd.to_datetime(data['issueDate'],format='%Y-%m-%d')
    startdate = datetime.datetime.strptime('2007-06-01','%Y-%m-%d')
    data['issueDateDT'] = data['issueDate'].apply(lambda x: x-startdate).dt.days

train['employmentLength'].value_counts(dropna=False).sort_index()

ここに画像の説明を挿入

オブジェクトタイプ特徴から数値特徴への変換

def employmentLength_to_int(s):
    if pd.isnull(s):
        return s
    else:
        return np.int8(s.split()[0])

for data in [train,testA]:
    data['employmentLength'].replace('10+ years','10 years', inplace=True)
    data['employmentLength'].replace('< 1 year','0 year', inplace=True)
    data['employmentLength'] = data['employmentLength'].apply(employmentLength_to_int)
data['employmentLength'].value_counts(dropna=False).sort_index()

ここに画像の説明を挿入

train['earliesCreditLine'].sample(5)

ここに画像の説明を挿入

for data in [train,testA]:
    data['earliesCreditLine'] = data['earliesCreditLine'].apply(lambda s: int(s[-4:]))

クラス特徴処理

cate_features = ['grade', 'subGrade', 'employmentTitle', 'homeOwnership','verificationStatus', 'purpose', 'postCode', 'regionCode', 'applicationType', 'initialListStatus', 'title', 'policyCode']
for f in cate_features:
    print(f, '类型数:', data[f].nunique())

ここに画像の説明を挿入

外れ値の処理

異常を検出する方法: 平均二乗誤差
def find_outliers_by_3segama(data,fea):
    data_std = np.std(data[fea])
    data_mean = np.mean(data[fea])
    outliers_cut_off = data_std*3
    lower_rule = data_mean - outliers_cut_off
    upper_rule = data_mean + outliers_cut_off
    data[fea+'_outliers'] = data[fea].apply(lambda x:str('异常值') if x > upper_rule or x < lower_rule else '正常值')
    return data
data_train = data_train.copy()
for fea in numerical_fea:
    data_train = find_outliers_by_3segama(data_train,fea)
    print(data_train[fea+'_outliers'].value_counts())
    print(data_train.groupby(fea+'_outliers')['isDefault'].sum())
    print('*'*10)

ここに画像の説明を挿入

## 删除异常值
for fea in numerical_fea:
    data_train = data_train[data_train[fea+'_outliers'] == '正常值']
    data_train = data_train.reset_index(drop=True)

データのバケット化

  • 特徴量ビニングの目的:
  • モデル効果の観点から見ると、特徴ビニングは主に変数の複雑さを軽減し、モデルに対する変数ノイズの影響を軽減し、独立変数と従属変数の間の相関を改善することを目的としています。これにより、モデルがより安定します。
  • データバケット化の対象:
  • 連続変数を離散化する
  • 複数状態の離散変数を少数状態にマージする
  • ビニングの理由:
  • データの特徴における値の範囲は比較的大きい場合があり、K 平均法クラスタリングなどの教師あり手法と教師なし手法では、ユークリッド距離を類似度関数として使用して、データ ポイント間の類似性を測定します。どちらも大小の影響を及ぼしますが、解決策の 1 つは、カウント値を間隔化し、データ バケット化 (データ ビニングとも呼ばれます) を行い、定量化された結果を使用することです。
  • ビニングの利点:
  • 欠損値の処理: データ ソースに欠損値がある可能性がある場合、現時点では null を別のビンとして使用できます。
  • 外れ値の処理: データに外れ値がある場合、ロバスト性 (耐干渉能力) を向上させるためにビニングによって外れ値を離散化できます。たとえば、年齢に異常値 200 があった場合、その影響を除外するために「年齢 > 60」のビンに分類できます。
  • ビジネスの説明: 私たちは変数の役割を線形に判断することに慣れており、x がどんどん大きくなると、y もどんどん大きくなります。ただし、x と y の間には非線形の関係が存在することが多く、現時点では WOE によって変換できます。
  • ビニングの基本原則に特に注意してください。
  • 最小ビニング率は 5% 以上です
  • 良い顧客全員が含まれるわけではない
  • 連続ビン単調
固定幅のビニング
当数值横跨多个数量级时,最好按照 10 的幂(或任何常数的幂)来进行分组:09、1099、100999、10009999,等等。固定宽度分箱非常容易计算,但如果计数值中有比较大的缺口,就会产生很多没有任何数据的空箱子。
# 通过除法映射到间隔均匀的分箱中,每个分箱的取值范围都是loanAmnt/1000
data['loanAmnt_bin1'] = np.floor_divide(data['loanAmnt'], 1000)
## 通过对数函数映射到指数宽度分箱
data['loanAmnt_bin2'] = np.floor(np.log10(data['loanAmnt']))
分位数分箱
data['loanAmnt_bin3'] = pd.qcut(data['loanAmnt'], 10, labels=False)
機能の相互作用
for col in ['grad','subGrade']:
    temp_dict = data_train.groupby([col])['isDefault'].agg(['mean']).reset_index().rename(columns={
    
    'mean':col+'_target_mean'})
    temp_dict.index = temp_dict[col].values
    temp_dict = temp_dict[col + '_target_mean'].to_dict()
    data_train[col + '_target_mean'] = data_train[col].map(temp_dict)
    data_test_a[col + '_target_mean'] = data_test_a[col].map(temp_dict)
# 其他衍生变量 mean 和 std
for df in [data_train, data_test_a]:
for item in
['n0','n1','n2','n2.1','n4','n5','n6','n7','n8','n9','n10','n11','n12','n13','n14']:
df['grade_to_mean_' + item] = df['grade'] / df.groupby([item])
['grade'].transform('mean')
df['grade_to_std_' + item] = df['grade'] / df.groupby([item])
['grade'].transform('std')

特徴エンコーディング

labelEncode はツリー モデルに直接入れられます
#label-encode:subGrade,postCode,title
# 高维类别特征需要进行转换
for col in tqdm(['employmentTitle', 'postCode', 'title','subGrade']):
le = LabelEncoder()
le.fit(list(data_train[col].astype(str).values) +
list(data_test_a[col].astype(str).values))
data_train[col] = le.transform(list(data_train[col].astype(str).values))
data_test_a[col] = le.transform(list(data_test_a[col].astype(str).values))
print('Label Encoding 完成')

機能の選択

  • フィルタ
    a. 分散選択法
    b. 相関係数法(ピアソン相関係数)
    c. カイ二乗検定
    d. 相互情報量法
  • ラッパー (RFE)
    a. 再帰的特徴除去方法
  • 埋め込み型
    a. ペナルティ項目に基づく特徴選択方法
    b. ツリーモデルに基づく特徴選択

おすすめ

転載: blog.csdn.net/BigCabbageFy/article/details/108719488