2016-09-04 16 views
4

Pythonで欠損値を代入しようとしていますが、sklearnは平均(平均、中央値、またはモード)補完以外の方法を持っていません。 Orange imputation modelは実行可能なオプションを提供するようです。しかし、Orange.data.Tablenp.nanを認識していないか、何らかの理由で補完が失敗しているようです。予測モデルを使用して欠損値を代入する

import Orange 
import numpy as np 

tmp = np.array([[1, 2, np.nan, 5, 8, np.nan], [40, 4, 8, 1, 0.2, 9]]) 
data = Orange.data.Table(tmp) 
imputer = Orange.feature.imputation.ModelConstructor() 
imputer.learner_continuous = Orange.classification.tree.TreeLearner(min_subset=20) 
imputer = imputer(data) 
impdata = imputer(data) 
for i in range(0, len(tmp)): 
    print impdata[i] 

出力は

[1.000, 2.000, 1.#QO, 5.000, 8.000, 1.#QO] 
[40.000, 4.000, 8.000, 1.000, 0.200, 9.000] 

私が行方不明です何任意のアイデアですか?ありがとう!

+0

'np.nan'を' None'に置き換えてみましたか? – pyCthon

+0

'None'を試してみましたが、この' TypeError:コンストラクタ(ドメインまたはサンプルまたは両方が期待される)の引数が無効です。 ' – sedeh

答えて

2

オレンジの欠損値は?または~と表示されているようです。奇妙なことに、​​コンストラクタは、numpy.nan?または~に変換され、代わりに1.#QOに変換されることを推論しません。以下のカスタム関数pandas_to_orange()は、この問題を解決します。

import Orange 
import numpy as np 
import pandas as pd 

from collections import OrderedDict 

# Adapted from https://github.com/biolab/orange3/issues/68 

def construct_domain(df): 
    columns = OrderedDict(df.dtypes) 

    def create_variable(col): 
     if col[1].__str__().startswith('float'): 
      return Orange.feature.Continuous(col[0]) 
     if col[1].__str__().startswith('int') and len(df[col[0]].unique()) > 50: 
      return Orange.feature.Continuous(col[0]) 
     if col[1].__str__().startswith('date'): 
      df[col[0]] = df[col[0]].values.astype(np.str) 
     if col[1].__str__() == 'object': 
      df[col[0]] = df[col[0]].astype(type("")) 
     return Orange.feature.Discrete(col[0], values = df[col[0]].unique().tolist()) 
    return Orange.data.Domain(list(map(create_variable, columns.items()))) 

def pandas_to_orange(df): 
    domain = construct_domain(df) 
    df[pd.isnull(df)]='?' 
    return Orange.data.Table(Orange.data.Domain(domain), df.values.tolist()) 

df = pd.DataFrame({'col1':[1, 2, np.nan, 4, 5, 6, 7, 8, 9, np.nan, 11], 
        'col2': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110.]}) 

tmp = pandas_to_orange(df) 
for i in range(0, len(tmp)): 
    print tmp[i] 

出力は次のようになります。

[1.000, 10.000] 
[2.000, 20.000] 
[?, 30.000] 
[4.000, 40.000] 
[5.000, 50.000] 
[6.000, 60.000] 
[7.000, 70.000] 
[8.000, 80.000] 
[9.000, 90.000] 
[?, 100.000] 
[11.000, 110.000] 

私は適切に欠損値をエンコードしたかった理由は、私はオレンジ帰属ライブラリを使用することができます。しかし、ライブラリ内の予測木モデルは、単純平均代用よりもはるかに機能しないように見えます。具体的には、すべての欠損値に対して同じ値を代入します。ここで

imputer = Orange.feature.imputation.ModelConstructor() 
imputer.learner_continuous = Orange.classification.tree.TreeLearner(min_subset=20) 
imputer = imputer(tmp) 
impdata = imputer(tmp) 
for i in range(0, len(tmp)): 
    print impdata[i] 

は出力です:

[1.000, 10.000] 
[2.000, 20.000] 
[5.889, 30.000] 
[4.000, 40.000] 
[5.000, 50.000] 
[6.000, 60.000] 
[7.000, 70.000] 
[8.000, 80.000] 
[9.000, 90.000] 
[5.889, 100.000] 
[11.000, 110.000] 

私は完全な例で、k最近傍を言う、モデルを当てはめると、不足している例を予測するためのフィットモデルを使用します何かを探していました。 fancyimpute (a Python 3 package)これは私の300K +入力にMemoryErrorをスローします。

from fancyimpute import KNN 

df = pd.DataFrame({'col1':[1, 2, np.nan, 4, 5, 6, 7, 8, 9, np.nan, 11], 
        'col2': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110.]}) 

X_filled_knn = KNN(k=3).complete(df) 
X_filled_knn 

出力は次のとおりです。

array([[ 1.  , 10.  ], 
     [ 2.  , 20.  ], 
     [ 2.77777784, 30.  ], 
     [ 4.  , 40.  ], 
     [ 5.  , 50.  ], 
     [ 6.  , 60.  ], 
     [ 7.  , 70.  ], 
     [ 8.  , 80.  ], 
     [ 9.  , 90.  ], 
     [ 9.77777798, 100.  ], 
     [ 11.  , 110.  ]]) 

私はおそらく回避策を見つけるか、チャンクに(理想的ではない)データセットを分割することができます。

1

Orange v2では、マスクされた配列numpyをOrange.data.Tableコンストラクタに渡すことができます。あなたの例を変更する:

import Orange 
import numpy as np 

tmp = np.array([[1, 2, np.nan, 5, 8, np.nan], [40, 4, 8, 1, 0.2, 9]]) 
tmp_masked = np.ma.masked_array(tmp, mask=np.isnan(tmp)) 
data = Orange.data.Table(tmp_masked) 
imputer = Orange.feature.imputation.ModelConstructor() 
imputer.learner_continuous = Orange.classification.tree.TreeLearner(min_subset=20) 
imputer = imputer(data) 
impdata = imputer(data) 
for i in range(0, len(tmp)): 
    print impdata[i] 
関連する問題