データ降次元方法及びPython実現


一、データ降次元の理解
1.1、データ降次元原理:機械学習領域における降次元とはある種のマッピング方法を採用し、元の高次元空間におけるデータ点を低次元の空間にマッピングすることである.次元を下げる本質は、マッピング関数f:x->yを学習することであり、xは元のデータ点の表現であり、現在はベクトル表現形式が最も使用されている.yはデータポイントマッピング後の低次元ベクトル表現であり、通常yの次元はxの次元より小さい(もちろん次元を高めることも可能である).fは、明示的または暗黙的、線形または非線形である可能性がある.
1.2、データの降次元を行わない可能性のある影響:データセットが多すぎるデータノイズを含む場合、アルゴリズムの性能が予想に達しない.情報量が少なく、無効な情報次元を削除すると、より拡張性があり、汎用性のあるデータモデルを構築できます.このデータモデルは、新しいデータセットでよりよく表現される可能性があります.
1.3、データ降次元の原則:データ列数を減らしながら、紛失したデータ情報をできるだけ少なくすることを保証する.
二、データ降次元作用
  • 時間の複雑さと空間の複雑さを低減する.
  • は、不要な特徴を抽出する費用を節約した.
  • データセットに混在するノイズデータを除去する.
  • より簡単なモデルは、小さなデータセットでより強いロバスト性を有する.
  • データが少ない特徴で解釈できる場合、データをよりよく解釈することができ、知識を抽出することができます.
  • は、データの可視化を実現する.

  • 三、データ降次元方法
    3.1.欠落値比率(Missing Value Ratio):この方法は、欠落値が多すぎるデータ列に基づいて有用な情報を含む可能性が少ない.したがって、データ列の欠落値がしきい値より大きい列を削除できます.しきい値が高いほど、次元を下げる方法がより積極的になります.すなわち、次元を下げる方法が少なくなります.
    ##     (     )
    
    def na_count(data):
        '''               '''
        data_count = data.count()
        na_count = len(data) - data_count
        na_rate = na_count/len(data)
        result = pd.concat([data_count,na_count,na_rate],axis = 1)
        return result
    
    def miss_data_handle(data):
        '''       '''
        table_col = data.columns
        table_col_list = table_col.values.tolist()          
        row_length = len(data)
        for col_key in table_col_list:
            non_sum1 = data[col_key].isnull().sum()
            if non_sum1/row_length >= 0.8:
                data[col_key] = data[col_key].dropna(axis = 1) 
        return data

    3.2、ランダム森林/組合せ木(Random Forests):組合せ決定木は通常ランダム森林となり、特徴選択と有効な分類器の構築に非常に有用である.一般的なディメンションダウン・メソッドの1つは、ターゲット・プロパティに多くの巨大なツリーを生成し、各プロパティの統計結果に基づいて情報量が最大のフィーチャー・サブセットを見つけることです.たとえば、非常に大きなデータセットに対して階層の浅いツリーを生成することができます.各ツリーは属性のほんの一部を訓練します.1つのプロパティが常に最適な分裂プロパティになる場合は、保持する必要がある情報フィーチャーである可能性があります.ランダム森林データ属性の統計的スコアは、他の属性と比較してどの属性が予測能力に最も優れているかを明らかにします.
    ##     (    /   )
    
    target_col = 'IS_SUCCESS'   #    
    ipt_col = list(data.columns)  #       
    
    def data_sample(data, col=target_col, smp=3):
        data_1 = data[data[col] == 1].sample(frac=1)
        data_0 = data[data[col] == 0].sample(n=len(data_1)*smp)
        data = pd.concat([data_1, data_0]).reset_index()
        return data
    
    def train_test_spl(data):
            '''    '''
            X_train, X_test, y_train, y_test = train_test_split(
                data[ipt_col], data[target_col], test_size=0.3, random_state=42)
            return X_train, X_test, y_train, y_test
    
    def feture_extracted(data):
        global ipt_col
        ipt_col= list(data.columns)
        ipt_col.remove(target_col)
        sample_present = [1, 2, 4, 6, 8, 10, 12, 15]   #       
        alpha = 0.9
        f1_score_list = []
        model_dict = {}
        for i in sample_present:
            try:
                data = data_sample(data, col=target_col, smp=i)
            except ValueError:
                break
            X_train, X_test, y_train, y_test = train_test_spl(data)  
            model = RandomForestClassifier()
            model = model.fit(X_train, y_train)
            model_pred = model.predict(X_test)
            f1_score = metrics.f1_score(y_test, model_pred)
            f1_score_list.append(f1_score)
            model_dict[i] = model
        max_f1_index = f1_score_list.index(max(f1_score_list))
        print('        :1:',sample_present[max_f1_index])
        d = dict(zip(ipt_col, [float('%.3f' %i) for i in model_dict[sample_present[max_f1_index]].feature_importances_]))
        f = zip(d.values(), d.keys())
        importance_df = pd.DataFrame(sorted(f, reverse=True), columns=['importance', 'feture_name'])
        list_imp = np.cumsum(importance_df['importance']).tolist()
        for i, j in enumerate(list_imp):
            if j >= alpha:
                break
        print('  alpha         :
    ',importance_df.iloc[0:i+1, :]) print(' :') feture_selected = importance_df.iloc[0:i+1, 1].tolist() print(feture_selected) return feture_selected

    3.3、低分散フィルタリング(Low Variance Filter):欠落値比率によるデータ次元ダウンの方法と似ており、データ列の変化が非常に小さい列に含まれる情報量が少ないと仮定する.したがって、すべてのデータ列の分散が小さい列が除去される.分散はデータ範囲に関連するため,この方法を採用する前にデータを正規化する必要があることに注意すべきである.
    ##     (     )
    
    var = data.var()
    numeric = data.columns
    variable = [ ]
    for i in range(0,len(var)):
        if var[i]>= 10:   #       10%
           variable.append(data[i+1])

    3.4、高相関フィルタリング(High Correlation Filter):高相関フィルタリングは、2列のデータの変化傾向が似ている場合、それらに含まれる情報も似ていると考えられる.これにより,類似列の1列を用いることで機械学習モデルを満たすことができる.数値列間の類似性は相関係数を計算することによって表され、データ型がカテゴリ型の相関係数はピルソンのカルバン値を計算することによって表すことができる.相関係数がしきい値より大きい2つのカラムは、1つのカラムのみを保持します.同様に,相関係数は範囲に敏感であるため,計算前にデータを正規化する必要がある.
    ##     (     )
    
    k = 0.8  #    
    def data_corr_analysis(data, sigmod = k):
        '''     :                                '''
        corr_data = data.corr()         
        for i in range(len(corr_data)):
            for j in range(len(corr_data)):
                if j == i:
                    corr_data.iloc[i, j] = 0
    
        x, y, corr_xishu = [], [], []
        for i in list(corr_data.index):         
            for j in list(corr_data.columns):  
                if abs(corr_data.loc[i, j]) > sigmod:        
                    x.append(i)
                    y.append(j)
                    corr_xishu.append(corr_data.loc[i, j])
        z = [[x[i], y[i], corr_xishu[i]] for i in range(len(x))]
        high_corr = pd.DataFrame(z, columns=['VAR1','VAR2','CORR_XISHU'])
        return high_corr
    

    3.5.主成分分析(PCA):主成分分析は、直交変換によって元のn次元データセットを主成分と呼ばれる新しいデータセットに変換する統計プロセスである.変換後の結果、第1の主成分は最大の分散値を有し、各後続の成分は前記主成分と直交する条件の制限下で最大の分散値を有する.ディメンションダウン時には、前のm(m3.5.1、主な思想:データを元の座標系から新しい座標系に変換し、新しい座標系の選択はデータ自身によって決定される:最初の新しい座標軸は元のデータの中で分散が最大の方向を選択し、2番目の新しい座標軸は最初の座標軸と直交し、分散が大きい方向を選択する.このプロシージャは、元のデータのフィーチャーの数で繰り返されます.ほとんどの分散は、一番前のいくつかの新しい座標軸に集中しています.したがって,残りの座標軸,すなわちデータの次元ダウン処理は無視できる.
    3.5.2、注意:
  • 主成分変換は直交ベクトルのスケールに敏感である.データは変換前に正規化処理が必要です.
  • の新しい主成分は実際のシステムによって生成されないため、PCA変換を行うとデータの解釈性が失われる.もし、データの解釈能力があなたの分析にとって重要だとしたら、PCAはあなたにとって適用されないかもしれません.
  • ##     (PCA)
    
    from sklearn.decomposition import PCA
    pca = PCA()  
    pca = PCA(n_components = None,copy = True,whiten = False)
    pca.fit(data)
    pca.components_ 
    pca.explained_variance_ratio_ 
    
    pca = PCA(3)  #          ,    PCA  
    pca.fit(data)
    low_d = pca.transform(data) 
    

    3.6、因子分析(FA):多数の変数間の内部依存関係を研究することによって、観測データ中の基本構造を探求し、少数の仮想変数でその基本データ構造を表す.これらの仮想変数は,元の多くの変数の主な情報を反映することができる.元の変数は観測可能な顕在変数であり,仮想変数は観測不可能な潜在変数であり,因子と呼ばれる.
    因子解析にはまた2つの方向が存在し,1つは探索的因子解析である.もう1つは検証因子解析である.探索因子解析は,一連の自己変数の背後にいくつかの因子があることを不確定にし,この方法によりこれらの因子を見つけようとした.検証因子解析は,自己変数の背後にいくつかの因子があると仮定し,この方法でこの仮定が正しいかどうかを検証しようとした.検証因子解析はまた構造方程式モデルと大きく関係している.
    ##     (FA)
    
    import pandas as pd
    import numpy as np
    import math
    df = pd.DataFrame(mydata)
    
    #      
    mydata_mean = mydata.mean()
    E = np.mat(np.zeros((14, 14)))
    for i in range(len(mydata)):
        E += (mydata.iloc[i, :].reshape(14, 1) - mydata_mean.reshape(14, 1)) * (mydata.iloc[i, :].reshape(1, 14) - mydata_mean.reshape(1, 14))
        
    #       
    R = np.mat(np.zeros((14, 14)))
    for i in range(14):
        for j in range(14):
            R[i, j] = E[i, j]/math.sqrt(E[i, i] * E[j, j])
            
    import numpy.linalg as nlg
    eig_value, eigvector = nlg.eig(R)
    eig = pd.DataFrame()
    eig['names'] = mydata.columns
    eig['eig_value'] = eig_value
    eig.sort_values('eig_value', ascending=False, inplace=True)
     
    #           ,        m
    for m in range(1, 14):
        if eig['eig_value'][:m].sum()/eig['eig_value'].sum() >= 0.8:
            print(m)
            break
    
     #      
    A  = np.mat(np.zeros((14, 6)))
    for i in range(5):
        A[:,i]=math.sqrt(eig_value[i])*eigvector[:,i]
    a=pd.DataFrame(A)
    a.columns=['factor1','factor2','factor3','factor4','factor5','factor6']
    

    3.7、逆特徴除去(Backward Feature Elimination):この方法では、すべての分類アルゴリズムがn個の特徴で訓練される.次元ダウン操作のたびに,n−1個の特徴を用いて分類器をn回訓練し,新しいn個の分類器を得た.新しい分類器で誤分率変化が最も小さい分類器で用いられるn−1次元特徴を降次元後の特徴セットとする.このプロセスを反復し続けると、次元が下がった結果が得られます.k回目の反復過程で得られたのはn−k次元特徴分類器である.最大のエラー許容率を選択することで,指定した分類性能の最小化に分類器を選択するのにどれだけの特徴が必要かを得ることができる.
    ##     (      )
    
    from sklearn.linear_model import LinearRegression
    from sklearn.feature_selection import RFE
    from sklearn import datasets
    
    df = data.drop('IS_SUCCESS', 1)
    lreg = LinearRegression()
    rfe = RFE(lreg, 10)
    rfe = rfe.fit_transform(df, data.IS_SUCCESS)
    

    3.8、フォワードフィーチャー構造(Forward Feature Construction):フォワードフィーチャー構築は逆フィーチャー除去の逆プロセスである.順方向特徴過程では,1つの特徴から始め,訓練ごとに分類器の性能を最大に向上させる特徴を追加した.順方向フィーチャーの構造と逆方向フィーチャーの除去には時間がかかります.通常、次元数が比較的低いデータセットを入力するために使用されます.
    ##     (      )
    
    from sklearn.feature_selection import f_regression
    ffs = f_regression(df,data.IS_SUCCESS)
    
    variable = [ ]
    for i in range(0,len(df.columns)-1):
        if ffs[0][i] >=10:
           variable.append(df.columns[i])

    データの次元ダウンには、上記のいくつかの他に、次のものが含まれます.
  • ランダム投影(Random Projections);
  • 非負行列分解(N 0 n-negative Matrix Factorization);
  • 自動符号化(Auto-encoders);
  • カード側検出と情報利得(Chi-square and information gain);
  • 多次元標定(Multidimensional Scale);
  • クラスタリングおよびベイズモデル