9

行列があるとします:

> import numpy as nap
> a = np.random.random((5,5))

array([[ 0.28164485,  0.76200749,  0.59324211,  0.15201506,  0.74084168],
       [ 0.83572213,  0.63735993,  0.28039542,  0.19191284,  0.48419414],
       [ 0.99967476,  0.8029097 ,  0.53140614,  0.24026153,  0.94805153],
       [ 0.92478   ,  0.43488547,  0.76320656,  0.39969956,  0.46490674],
       [ 0.83315135,  0.94781119,  0.80455425,  0.46291229,  0.70498372]])

np.NaNそして、たとえば次のように、いくつかの穴を開けます。

> a[(1,4,0,3),(2,4,2,0)] = np.NaN; 

array([[ 0.80327707,  0.87722234,         nan,  0.94463778,  0.78089194],
       [ 0.90584284,  0.18348667,         nan,  0.82401826,  0.42947815],
       [ 0.05913957,  0.15512961,  0.08328608,  0.97636309,  0.84573433],
       [        nan,  0.30120861,  0.46829231,  0.52358888,  0.89510461],
       [ 0.19877877,  0.99423591,  0.17236892,  0.88059185,        nan ]])

nanマトリックスの残りのエントリからの情報を使用してエントリを記入したいと思います。例として、エントリが発生する列の平均値を使用します。nan

より一般的には、マトリックス補完用の Python のライブラリはありますか? (たとえば、 Candes & Recht の凸最適化法に沿ったもの)。

バックグラウンド:

この問題は、機械学習でよく見られます。たとえば、分類/回帰または協調フィルタリングで欠落している機能を操作する場合 (たとえば、ウィキペディアの Netflix 問題とここを参照してください)

4

5 に答える 5

12

最新の scikit-learn バージョン 0.14a1 をインストールすると、その光沢のある新しいImputerクラスを使用できます。

>>> from sklearn.preprocessing import Imputer
>>> imp = Imputer(strategy="mean")
>>> a = np.random.random((5,5))
>>> a[(1,4,0,3),(2,4,2,0)] = np.nan
>>> a
array([[ 0.77473361,  0.62987193,         nan,  0.11367791,  0.17633671],
       [ 0.68555944,  0.54680378,         nan,  0.64186838,  0.15563309],
       [ 0.37784422,  0.59678177,  0.08103329,  0.60760487,  0.65288022],
       [        nan,  0.54097945,  0.30680838,  0.82303869,  0.22784574],
       [ 0.21223024,  0.06426663,  0.34254093,  0.22115931,         nan]])
>>> a = imp.fit_transform(a)
>>> a
array([[ 0.77473361,  0.62987193,  0.24346087,  0.11367791,  0.17633671],
       [ 0.68555944,  0.54680378,  0.24346087,  0.64186838,  0.15563309],
       [ 0.37784422,  0.59678177,  0.08103329,  0.60760487,  0.65288022],
       [ 0.51259188,  0.54097945,  0.30680838,  0.82303869,  0.22784574],
       [ 0.21223024,  0.06426663,  0.34254093,  0.22115931,  0.30317394]])

この後、から学習しimp.transformた平均を使用して、他のデータに同じ変換を行うためにを使用できます。インピューターは scikit-learnオブジェクトに関連付けられているため、分類パイプラインまたは回帰パイプラインで使用できます。impaPipeline

安定版のリリースを待ちたい場合は、0.14 が来週リリースされるはずです。

完全開示: 私は scikit-learn コア開発者です

于 2013-08-01T18:34:11.730 に答える
4

あなたが望む正確な方法 (Candes and Recht, 2008) はfancyimpute、ここ (リンク) にあるライブラリの Python で利用できます。

from fancyimpute import NuclearNormMinimization

# X is the complete data matrix
# X_incomplete has the same values as X except a subset have been replace with NaN

X_filled_nnm = NuclearNormMinimization().complete(X_incomplete)

私はそれから良い結果を見てきました。ありがたいことに、彼らは autodiff と SGD バックエンドを、内部downhillで使用するTheanoからkeras過去 1 年の間に変更しました。アルゴリズムはこのライブラリでも利用できます (リンク)。SciKit-LearnImputer()には、このアルゴリズムは含まれていません。ドキュメントにはありませんが、次の方法でインストールできfancyimputeますpip

pip install fancyimpute
于 2018-08-01T01:15:18.220 に答える
2

同様の質問が以前ここで尋ねられ ました。必要なのはinpaitingの特別なケースです。残念ながら、numpy にも scipy にも、このための組み込みルーチンはありません。ただし、OpenCV には関数がありますが、8 ビット イメージでしか動作しません。 inpaint()

OpenPIVには、replace_nans目的に合わせて使用​​できる機能があります。(ライブラリ全体をインストールしたくない場合に再パッケージできるCythonバージョンについては、こちらを参照してください。)他の回答で提案されているように、古い値の純粋な平均または伝播よりも柔軟です(たとえば、さまざまな重み関数を定義できます、カーネルサイズなど)。

@Ophion の例を使用しreplace_nansて、nanmeanと Pandas のソリューションを比較しました。

import numpy as np
import pandas as pd
from scipy.stats import nanmean

a = np.random.random((10000,10000))
col=np.random.randint(0,10000,500)
row=np.random.randint(0,10000,500)
a[(col,row)]=np.nan
a1=np.copy(a)

%timeit new_array = replace_nans(a1, 10, 0.5, 1.)
1 loops, best of 3: 1.57 s per loop

%timeit mean=nanmean(a,axis=0);index=np.where(np.isnan(a));a[index]=np.take(mean,index[1])
1 loops, best of 3: 2.23 s per loop

%timeit DF=pd.DataFrame(a1);col_means = DF.apply(np.mean, 0);DF.fillna(value=col_means)
1 loops, best of 3: 7.23 s per loop

このreplace_nansソリューションは間違いなく優れており、高速です。

于 2013-08-01T12:56:24.037 に答える