Python中的矩阵完成

Ame*_*ina 9 python numpy machine-learning mathematical-optimization scikit-learn

说我有一个矩阵:

> 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]])
Run Code Online (Sandbox Code Playgroud)

而且我用它打了一些洞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 ]])
Run Code Online (Sandbox Code Playgroud)

我想nan使用矩阵其余条目的信息填写条目.一个例子是使用条目出现的列的平均值nan.

更一般地说,Python中是否有用于矩阵完成的库?(例如Candes&Recht的凸优化方法).

背景:

这个问题经常出现在机器学习中.例如,在分类/回归或协同过滤中使用缺少的功能时(例如,请参阅Wikipedia上的Netflix问题和此处)

Fre*_*Foo 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]])
Run Code Online (Sandbox Code Playgroud)

在此之后,您可以使用从中学习imp.transform的平均值对其他数据进行相同的转换.Imputers与scikit-learn 对象结合使用,因此您可以在分类或回归管道中使用它们.impaPipeline

如果你想等待一个稳定的释放,那么下周应该是0.14.

完全披露:我是一个scikit-learn核心开发人员


Dan*_*iel 5

你可以用纯粹的numpy来做,但它更糟糕.

from scipy.stats import nanmean
>>> a
array([[ 0.70309466,  0.53785006,         nan,  0.49590115,  0.23521493],
       [ 0.29067786,  0.48236186,         nan,  0.93220001,  0.76261019],
       [ 0.66243065,  0.07731947,  0.38887545,  0.56450533,  0.58647126],
       [        nan,  0.7870873 ,  0.60010096,  0.88778259,  0.09097726],
       [ 0.02750389,  0.72328898,  0.69820328,  0.02435883,         nan]])


>>> mean=nanmean(a,axis=0)
>>> mean
array([ 0.42092677,  0.52158153,  0.56239323,  0.58094958,  0.41881841])
>>> index=np.where(np.isnan(a))

>>> a[index]=np.take(mean,index[1])
>>> a
array([[ 0.70309466,  0.53785006,  0.56239323,  0.49590115,  0.23521493],
       [ 0.29067786,  0.48236186,  0.56239323,  0.93220001,  0.76261019],
       [ 0.66243065,  0.07731947,  0.38887545,  0.56450533,  0.58647126],
       [ 0.42092677,  0.7870873 ,  0.60010096,  0.88778259,  0.09097726],
       [ 0.02750389,  0.72328898,  0.69820328,  0.02435883,  0.41881841]])
Run Code Online (Sandbox Code Playgroud)

运行一些时间:

import time
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 mean=nanmean(a,axis=0);index=np.where(np.isnan(a));a[index]=np.take(mean,index[1])
1 loops, best of 3: 1.84 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: 5.81 s per loop

#Surprisingly, issue could be apply looping over the zero axis.
DF=pd.DataFrame(a2)
%timeit col_means = DF.apply(np.mean, 0);DF.fillna(value=col_means)
1 loops, best of 3: 5.57 s per loop
Run Code Online (Sandbox Code Playgroud)

我不相信numpy内置了数组完成例程; 但是,熊猫呢.在此处查看帮助主题.


Ada*_*son 5

您想要的确切方法(Candes 和 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)
Run Code Online (Sandbox Code Playgroud)

我从中看到了良好的结果。值得庆幸的是,他们在过去的一年中将底层downhill使用的autodiff 和 SGD 后端更改为。该算法也可在该库中使用(链接)。SciKit-Learn不包含此算法。它不在文档中,但您可以使用以下命令安装:TheanokerasImputer()fancyimputepip

pip install fancyimpute
Run Code Online (Sandbox Code Playgroud)