特長作品(上)

特徴選択(feature_selection)

フィルタ

  1. 低分散特性(低分散の特徴を除去)除去
  2. 単変量特徴選択(単変量特徴選択)

ラッパー

  1. 再帰的な特徴の除去(再帰的機能の排除)

埋め込み

  1. SelectFromModel選択機能(SelectFromModelを使用して特徴選択)を使用します
  2. パイプラインに特徴選択プロセス(パイプラインの一部として特徴選択)

データの前処理が完了すると、私たちは訓練のための機械学習アルゴリズムやモデルの意味の入力特性を選択する必要があります。

一般的に選択された2つの機能の観点から言えば、:

特長は発散しています

機能が発散しない場合、例えば、分散がこの試料において、すなわち、ゼロに近い実質的に差がない、試料及び無使用の際立った特徴。

ターゲットとの相関

これは、好ましくは、選択すべき、目標特性との間の高い相関との比較から明らかです。低分散法を除去することに加えて、この資料に記載された他の方法は、関連する考察からです。

特徴選択は、特徴選択の形態であっても三種類に分けることができます。

  • フィルタ:濾過、または様々な特徴の相関スコアの広がりに応じて、閾値または閾値数が、選択された機能を選択します。
  • ラッパー:各番号、または負の特性の数を選択し、前記目的関数(通常予測効果スコア)に記載の梱包方法。
  • 埋め込み:埋め込み、特定のアルゴリズムの使用と機械学習モデルに選択機能を降順で係数に基づいて、各特徴量の重み係数を訓練されます。フィルタ方法は同様であるが、トレーニングの利点の特性によって決定されます。

特徴選択は、主に2つの目的があります。

  • オーバーフィッティング削減するためのモデルより汎化能力を作るために、機能の数、次元削減を減らします。

  • 間の機能と特徴値の強化理解。

データセットを取得し、特徴選択は、同時に2つの目的を完了することが困難な場合が多いです。一般的に、彼らが最も精通している、または最も便利な機能の選択方法(特性およびデータを理解する目的を無視して、多くの場合、次元削減の目的)を選択します。例としては、次のいくつかの共通の特徴選択方法、その利点、欠点や問題点をScikit-学ぶ提供されます。

フィルタ

1)機能、低分散を(低分散の機能を削除)削除

それは、この機能を達成できないことであり、実施例1の値の95%を特徴と機能特性値のみ0と1、およびすべての入力サンプルを、仮定する。100%が1である場合、これは何の意味を備えていません。固有値は、このメソッドを使用するために、離散変数がある場合、それは連続変数である場合は、使用する前に、我々は連続変数を離散化する必要があります。また、一般的に95%未満は、特性値が存在して撮影していますので、この方法はシンプルですが、使用することは容易ではない、練習します。小さな変化特性値を削除して述べ、以下の特徴の適切な選択方法はさらに、特徴選択を選択するために、予め選択として特徴付けることができます。

from sklearn.feature_selection import VarianceThreshold
X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
# 方差低于此阈值的特征将被删除
sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
sel.fit_transform(X)
array([[0, 1],
       [1, 0],
       [0, 0],
       [1, 1],
       [1, 0],
       [1, 1]])

確かに、VarianceThreshold機能は、最初の列は0 5/6の確率に到達する第1カラムに除去されます。

2)一変量特徴選択(一変量特徴選択)

一変量特徴選択原理は、個々の変数が重要これらの変数を排除することが重要であるかを決定するためにインデックスに従って、各変数の統計指標を算出します。

分類問題(Y離散)のために、使用することができます。

  • カイ二乗検定
  • f_classif
  • mutual_info_classif
  • 相互の情報

回帰問題(連続Y)のために、使用することができます。

  • ピアソン相関係数
  • f_regression、
  • mutual_info_regression
  • 最大係数情報

この方法は、一般的に良い効果があります(ただし、汎化能力改善のための最適化機能は、効果的ではないかもしれない)のデータを理解するために、理解しやすい、簡単操作、比較的簡単です。

  • K名のスコア以外のすべての機能の前に除去SelectKBest(トップはKを取ります)
  • SelectPercentileユーザーの割合を指定したスコアを除去した後ことを特徴とする(最上位k個の%をとら)
  • 各ジェネリック機能の単変量統計的検定:偽陽性率(偽陽性率)SelectFpr、擬似発見率(偽発見率)SelectFdr、エラーレート、あるいは家族のSelectFwe。
  • GenericUnivariateSelectは、単変量特徴選択に異なる戦略を設定することができます。同時に、異なる選択戦略はまた、我々は最高の単変量特徴選択戦略を見つけるように、超パラメータの最適化を使用することができます。

注意:
  。ON-Fベースの試験方法の2つのランダム変数の一方(2つの確率変数の線形相関のためのF.評価試験)BETWEEN推定度の線形依存性は、相互情報量法は、統計的な依存性の任意の種類を捕捉することができます。 しかし、ノンパラメトリックであり、それらはより必要と正確な推定のためのサンプルを( 一方、相互情報は統計的依存の任意のタイプをキャプチャすることができるが、ノンパラメトリック法として、より正確な試料の必要性を推定するために)

カイ二乗(Chi2)テスト

古典的なカイ二乗検定は、独立変数、従属変数の間の定性的な関係のための定性的試験です。例えば、我々は最高の二つの特徴を選択するために、chi2の試験サンプルを行うことができます。

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
iris = load_iris()
X, y = iris.data, iris.target
X.shape
(150, 4)
X[:5, :]
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2]])
X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
X_new.shape
(150, 2)
X_new[:5, :]
array([[1.4, 0.2],
       [1.4, 0.2],
       [1.3, 0.2],
       [1.5, 0.2],
       [1.4, 0.2]])
  • f_classif
    分類タスクのためのラベル/機能間のANOVA F値。

  • mutual_info_classif
    離散ターゲットの相互情報。

  • chi2
    分類タスクのための非負機能のカイ二乗統計。

  • f_regression
    回帰タスク用ラベル/機能間のF値。

  • mutual_info_regression
    連続ターゲットの相互情報を。

  • SelectPercentile
    選択は、最も高いスコアのパーセンタイルに基づいています。

  • SelectFpr
    偽陽性率テストに基づいて機能を選択します。

  • SelectFdr
    選択は、推定偽発見率に基づいています。

  • SelectFwe
    家族的なエラー率に基づいて機能を選択します。

  • GenericUnivariateSelect
    設定可能なモードでの単変量機能セレクター。

ピアソン相関係数(ピアソン相関)

ピアソンの相関係数を変数と応答特性との関係を理解するために、最も簡単なの一つであり、この方法は、変数間の線形相関を測定し、結果は値の間隔は[-1,1]、 -1 0は線形相関がないことを示し、+ 1が完全な正の相関を示し、完全な負の相関を示しています。

import numpy as np
from scipy.stats import pearsonr
np.random.seed(0)
size = 300
x = np.random.normal(0, 1, size)
# pearsonr(x, y)的输入为特征矩阵和目标向量,能够同时计算 相关系数 和p-value.
print("Lower noise", pearsonr(x, x + np.random.normal(0, 1, size)))
print("Higher noise", pearsonr(x, x + np.random.normal(0, 10, size)))
Lower noise (0.7182483686213841, 7.32401731299835e-49)
Higher noise (0.057964292079338155, 0.3170099388532475)

この例では、我々は前にノイズや変数を追加した後の違いを比較しました。ノイズが比較的小さい場合には、強い相関が、p値は非常に低いです。

私たちは、ピアソン相関係数が特徴の間ではなく、間と従属変数の相関関係を確認するために主に使用しました。

ラッパー

再帰的な特徴の除去(再帰的機能の排除)

右、新しい機能セットに基づいて、トレーニングの次のラウンドの係数のいくつかの特性値を除去するために、各ラウンドの後に、再帰的特徴脱離基モデルトレーニングの複数回、訓練を用いる方法。

再予測モデルを再帰的に検査のサイズを小さくすることを特徴と特徴の(例えば、線形モデルパラメータ係数に対応)、RFE選択されたセットの権利を含むことを特徴とします。まず、訓練のオリジナルの特徴の予測モデルは、それぞれの特徴は、重みを指定します。その後、最小量の絶対値は、特徴セットを蹴られていることを特徴とします。再帰など、数が残りの特徴必要な機能の数に達するまで。

特徴の最適数を選択するために、クロスバリデーションによって実行RFECVのRFE:機能セットの数をD、2乗Dの彼の部分集合の全ての数マイナス1(空集合を含みます)。このようSVMなどの外部の学習アルゴリズムを指定します。検証エラーによってすべてのアルゴリズムのサブセットを計算します。最小誤差を選択することは、その機能のサブセットとして選択されています。

from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

rf = RandomForestClassifier()
iris=load_iris()
X,y=iris.data,iris.target
print(X.shape)
print(X[:5, :])
(150, 4)
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]]
# 使用递归特征消除进行特征排序
rfe = RFE(estimator=rf, n_features_to_select=3)
X_rfe = rfe.fit_transform(X,y)
print(X_rfe.shape)
print(X_rfe[:5, :])
(150, 3)
[[5.1 1.4 0.2]
 [4.9 1.4 0.2]
 [4.7 1.3 0.2]
 [4.6 1.5 0.2]
 [5.  1.4 0.2]]


E:\Anaconda3\envs\sklearn\lib\site-packages\sklearn\ensemble\forest.py:248: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22.
  "10 in version 0.20 to 100 in 0.22.", FutureWarning)
E:\Anaconda3\envs\sklearn\lib\site-packages\sklearn\ensemble\forest.py:248: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22.
  "10 in version 0.20 to 100 in 0.22.", FutureWarning)

埋め込み

SelectFromModel選択機能(SelectFromModelを使用して特徴選択)を使用します

from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

clf = RandomForestClassifier()
iris=load_iris()
X,y=iris.data,iris.target
print(X.shape)
print(X[:5, :])
sfm = SelectFromModel(clf, threshold=0.25)
X_sfm = sfm.fit_transform(X,y)
print(X_sfm.shape)
print(X_sfm[:5, :])
(150, 4)
[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]]
(150, 2)
[[1.4 0.2]
 [1.4 0.2]
 [1.3 0.2]
 [1.5 0.2]
 [1.4 0.2]]


E:\Anaconda3\envs\sklearn\lib\site-packages\sklearn\ensemble\forest.py:248: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22.
  "10 in version 0.20 to 100 in 0.22.", FutureWarning)

特徴選択(L1ベースの特徴選択)L1は、ベース

線形モデル(線形モデル)を使用して、L1ノルムは疎液を献上する:ほとんどの特性係数が0に対応します。あなたが他の時間のために機能分類器の寸法を小さくしたいときは、0のfeature_selection.SelectFromModel係数によって選択することができません。

具体的には、一般に、この目的のために使用されるスパース予測モデルはlinear_model.Lasso(リターン)、linear_model.LogisticRegression及びsvm.LinearSVC(分類)であります

from sklearn.feature_selection import SelectFromModel
from sklearn.svm import LinearSVC
print(X.shape)
lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X,y)
model = SelectFromModel(lsvc, prefit=True)
X_embed = model.transform(X)
X_embed.shape
(150, 4)





(150, 3)
X_embed[:5,:]
array([[5.1, 3.5, 1.4],
       [4.9, 3. , 1.4],
       [4.7, 3.2, 1.3],
       [4.6, 3.1, 1.5],
       [5. , 3.6, 1.4]])

だから我々はどのように動作することを好みますか?

まずは、ビジネスモデルで、我々は何の問題がどうなるか見てみましょう。

  • モデルの結果ではありません
  • トレーニング効果的な設定、クロスタイム試験の結果ではありません
  • テスト結果の時間越えたり、ラインに悪影響後
  • 行の後に良い結果、スコアの分布は、数週間後に減少し始めました
  • 1,2ヶ月以内に、スコアの突然急落分布は比較的安定しています
  • 明白な問題はないが、緩やかな故障モデル毎月

その後、我々は必要なものをビジネス変数について考えてみると。

  • 変数は、顧客ベースを区別することができなければならないモデルに貢献しなければなりません
  • 独立変数の論理的な要件の間の線形回帰
  • ロジスティック回帰スコアカードも(ターニングポイント単調な変数の変数よりも必ずしも良くなく、ビジネス上の理由のために、部分的にも、しかし、ビューのモデル・ポイント)変数単調傾向が欲しいです
  • 変数の各における安定顧客ベースのディストリビューションは、移行の分布が不可避であるが、あまり変動しません

この目的のために、我々は最高の、上記の方法から現在の使用状況に合わせて、いくつかの方法を発見しました。

import pandas as pd
import numpy as np
df_train = pd.read_csv('train.csv')
df_train.head()
PassengerId ラベル PCLASS 性別 年齢 SibSp 牧師 チケット 運賃 キャビン 着手
0 1 0 3 Braund、氏オーウェン・ハリス 男性 22.0 1 0 / 5 21171 7.2500 NaNの S
1 2 1 1 カミングス、夫人ジョン・ブラッドリー(フィレンツェブリッグスのTh ... 女性 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen、ミス。ローン 女性 26.0 0 0 STON / O2。3101282 7.9250 NaNの S
3 4 1 1 Futrelle、夫人ジャック・ヒース(リリー月ピール) 女性 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 アレン、ウィリアム・ヘンリー氏 男性 35.0 0 0 373450 8.0500 NaNの S

1)変数の重要性

  • IV値
  • カイ二乗検定
  • スクリーニングモデル

ここでは、IV、またはもう少しスクリーニングモデルを使用します

IVは、実際にWOEの前のプラスです。

  • $ P_ {Y_I} = \ FRAC {Y_I} {y_T} $
  • $ P_ {n_i} = \ FRAC {n_i} {N_T} $
  • $ woe_i = LN(\ FRAC {P_ {Y_I}} {P_ {n_i}})$
  • $ iv_i =(P_ {Y_I} - P_ {n_i})回woe_i $ \

最後に、ちょうどIVの各区間については、IVの合計値を導出するために一緒に追加しました:
$$ IV = \ SUMのiv_iを$$

import math
a = 0.4  
b = 0.6
iv = (a - b) * math.log(a / b)
iv
0.08109302162163284

重要なのか、統合モデルの出力特性:

# lightGBM中的特征重要性
feature = pd.DataFrame(
            {'name' : model.booster_.feature_name(),
            'importance' : model.feature_importances_
          }).sort_values(by =  ['importance'],ascending = False)

2)共直線

  • 相関係数COR
  • 拡張のVIFの変動係数

モデルベースの空間分割思考の多くを行う、私たちは、変数間の相関関係に注意を払う必要があります。私たちは、ピアソン相関係数を使用する2つの変数を分離見えます。

df_train.corr()
PassengerId ラベル PCLASS 年齢 SibSp 牧師 運賃
PassengerId 1.000000 -0.005007 -0.035144 0.036847 -0.057527 -0.001652 0.012658
ラベル -0.005007 1.000000 -0.338481 -0.077221 -0.035322 0.081629 0.257307
PCLASS -0.035144 -0.338481 1.000000 -0.369226 0.083081 0.018443 -0.549500
年齢 0.036847 -0.077221 -0.369226 1.000000 -0.308247 -0.189119 0.096067
SibSp -0.057527 -0.035322 0.083081 -0.308247 1.000000 0.414838 0.159651
牧師 -0.001652 0.081629 0.018443 -0.189119 0.414838 1.000000 0.216225
運賃 0.012658 0.257307 -0.549500 0.096067 0.159651 0.216225 1.000000
import seaborn as sns
sns.set(color_codes=True)
np.random.seed(sum(map(ord, "distributions")))
# 在数据集中绘制成对关系
sns.pairplot(df_train) # 对角线上是单维度分布
<seaborn.axisgrid.PairGrid at 0xe7abfa160>

重回帰では、我々は深刻な多重共に問題があるかどうかVIF分散拡大係数回帰モデルを計算することによって確認することができます。定義:

$$ VIF = \ FRAC {1} {1-R ^ 2} $$

残りの引数の負の相関係数、回帰分析のための独立変数としての、$ R_iと$。拡張寛容$ 1-R ^ 2 $の逆数の分散係数。

分散のVIF膨張係数が独立変数の間の共線の存在のより高い可能性を示します。一般的に、分散インフレ率は10、回帰モデルの深刻な多重共を超えた場合。引数がある場合、まだ髪(1995)共線基準によれば、10未満の0.1より大きい公差変動範囲膨張係数は、変数間には明確なプレゼンステーブル共線的に許容されません。

VIF機能詳しい使い方を見ることができるstatsmodelsの公式文書を

from statsmodels.stats.outliers_influence import variance_inflation_factor
import numpy as np

data = [[1,2,3,4,5],
        [2,4,6,8,9],
        [1,1,1,1,1],
       [2,4,6,4,7]]
X = np.array(data).T

variance_inflation_factor(X,0)
98.33333333333381

3)単調性

  • bivarマップ
# 等频切分
df_train.loc[:,'fare_qcut'] = pd.qcut(df_train['Fare'], 10)
print(df_train.head())
df_train = df_train.sort_values('Fare')
alist = list(set(df_train['fare_qcut']))
badrate = {}
for x in alist:
    
    a = df_train[df_train.fare_qcut == x]
    
    bad = a[a.label == 1]['label'].count()
    good = a[a.label == 0]['label'].count()
    
    badrate[x] = bad/(bad+good)
badrate
     PassengerId  label  Pclass                             Name   Sex   Age  \
271          272      1       3     Tornquist, Mr. William Henry  male  25.0   
277          278      0       2      Parkes, Mr. Francis "Frank"  male   NaN   
263          264      0       1            Harrison, Mr. William  male  40.0   
597          598      0       3              Johnson, Mr. Alfred  male  49.0   
302          303      0       3  Johnson, Mr. William Cahoone Jr  male  19.0   

     SibSp  Parch  Ticket  Fare Cabin Embarked       fare_qcut  
271      0      0    LINE   0.0   NaN        S  (-0.001, 7.55]  
277      0      0  239853   0.0   NaN        S  (-0.001, 7.55]  
263      0      0  112059   0.0   B94        S  (-0.001, 7.55]  
597      0      0    LINE   0.0   NaN        S  (-0.001, 7.55]  
302      0      0    LINE   0.0   NaN        S  (-0.001, 7.55]  





{Interval(39.688, 77.958, closed='right'): 0.5280898876404494,
 Interval(14.454, 21.679, closed='right'): 0.42045454545454547,
 Interval(7.55, 7.854, closed='right'): 0.2988505747126437,
 Interval(8.05, 10.5, closed='right'): 0.23076923076923078,
 Interval(10.5, 14.454, closed='right'): 0.42857142857142855,
 Interval(77.958, 512.329, closed='right'): 0.7586206896551724,
 Interval(-0.001, 7.55, closed='right'): 0.14130434782608695,
 Interval(27.0, 39.688, closed='right'): 0.37362637362637363,
 Interval(7.854, 8.05, closed='right'): 0.1792452830188679,
 Interval(21.679, 27.0, closed='right'): 0.5168539325842697}
f = zip(badrate.keys(),badrate.values())
f = sorted(f,key = lambda x : x[1],reverse = True )
badrate = pd.DataFrame(f)
badrate
0 1
0 (77.958、512.329] 0.758621
1 (39.688、77.958] 0.528090
2 (21.679、27.0] 0.516854
3 (10.5、14.454] 0.428571
4 (14.454、21.679] 0.420455
5 (27.0, 39.688] 0.373626
6 (7.55, 7.854] 0.298851
7 (8.05, 10.5] 0.230769
8 (7.854, 8.05] 0.179245
9 (-0.001, 7.55] 0.141304
badrate.columns = pd.Series(['cut','badrate'])
badrate = badrate.sort_values('cut')
print('===============================================')
print(badrate)
badrate.plot('cut','badrate')
===============================================
                 cut   badrate
9     (-0.001, 7.55]  0.141304
6      (7.55, 7.854]  0.298851
8      (7.854, 8.05]  0.179245
7       (8.05, 10.5]  0.230769
3     (10.5, 14.454]  0.428571
4   (14.454, 21.679]  0.420455
2     (21.679, 27.0]  0.516854
5     (27.0, 39.688]  0.373626
1   (39.688, 77.958]  0.528090
0  (77.958, 512.329]  0.758621





<matplotlib.axes._subplots.AxesSubplot at 0xe018a4550>

4)稳定性

  • PSI
  • 跨时间交叉检验

跨时间交叉检验

就是将样本按照月份切割,一次作为训练集和测试集来训练模型,取进入模型的变量之间的交集,但是要小心共线特征!

解决方法

  • 不需要每次都进入模型,大部分都在即可
  • 先去除共线性(这也是为什么集成模型我们也会去除共线性)

群体稳定性指标(population stability index)

公式:

$$ PSI = \sum{(实际占比-预期占比)*{\ln(\frac{实际占比}{预期占比})}}$$

来自知乎的例子:
比如训练一个logistic回归模型,预测时候会有个概率输出p。
你测试集上的输出设定为p1吧,将它从小到大排序后10等分,如0-0.1,0.1-0.2,......。
现在你用这个模型去对新的样本进行预测,预测结果叫p2,按p1的区间也划分为10等分。
实际占比就是p2上在各区间的用户占比,预期占比就是p1上各区间的用户占比。
意义就是如果模型跟稳定,那么p1和p2上各区间的用户应该是相近的,占比不会变动很大,也就是预测出来的概率不会差距很大。
一般认为psi小于0.1时候模型稳定性很高,0.1-0.25一般,大于0.25模型稳定性差,建议重做。

def var_PSI(dev_data, val_data):
    dev_cnt, val_cnt = sum(dev_data), sum(val_data)
    if dev_cnt * val_cnt == 0:
        return None
    PSI = 0
    for i in range(len(dev_data)):
        dev_ratio = dev_data[i] / dev_cnt
        val_ratio = val_data[i] / val_cnt + 1e-10
        psi = (dev_ratio - val_ratio) * math.log(dev_ratio/val_ratio)
        PSI += psi
    return PSI

注意分箱的数量将会影响着变量的PSI值。

PSI并不只可以对模型来求,对变量来求也一样。只需要对跨时间分箱的数据分别求PSI即可。

おすすめ

転載: www.cnblogs.com/chenxiangzhen/p/10929971.html