我有一个从机器学习算法得到的浮点数列表。所有这些浮点数介于0和1之间:
probs = [proba[0] for proba in self.classifier.predict_proba(x_test)]
probs是我的浮动列表。 predict_proba()函数通常返回一个numpy数组。获取列表大约需要9秒钟,列表最终包含大约60k的值。
我想将列表中的所有值与列表中的最高值进行缩放或标准化。
通常,我会这样做:
maximum = max(probs)
list_values = [proba / maximum for proba in probs]
但是对于60k的值,大约需要2分钟。我想缩短它。
你对我如何参加更好的演出有什么想法吗?
答案 0 :(得分:2)
如果您不介意使用外部库,numpy可能值得研究:
import numpy
probs = numpy.array([proba[0] for proba in self.classifier.predict_proba(x_test)])
list_values = probs/maximum
答案 1 :(得分:0)
使用numpy的另一种方法,如果你的概率列表很大,可能会更快,就是将整个概率转换为numpy数组,然后对它进行操作:
import numpy as np
probs = np.asarray(self.classifier.predict_proba(x_test))
list_values = probs[:, 0] / probs.max()
第一行会将您的所有概率转换为N x M
数组(其中N
是您的样本,M
是您的班级数。)
第二行将选择第一个类的所有概率([:, 0]
表示第0列的所有行,这将产生大小为N
的向量)并将其除以最大值。
您可以将此扩展到所有概率:
all_probs = probs / probs.max()
以上将对所有类的所有概率进行标准化。之后您可以像all_probs[:, i]
那样访问它们,其中i
是感兴趣的类。
答案 2 :(得分:0)
你应该使用Scikit learn's normalize。
from sklearn.preprocessing import normalize
答案 3 :(得分:0)
如果您希望最终结果为numpy.array
,那么将列表转换为numpy数组并直接使用数组除法将比列表理解更快。示例 -
import numpy as np
probsnp = np.array([proba[0] for proba in self.classifier.predict_proba(x_test)])
maximum = probs.max()
list_values = probs/maximum
时间测试的例子 -
In [46]: import numpy.random as ndr
In [47]: probs = ndr.random_sample(1000)
In [48]: probs.shape
Out[48]: (1000,)
In [49]: def func1(probs):
....: maximum = max(probs)
....: probsnew = [i/maximum for i in probs]
....: return probsnew
....:
In [50]: def func2(probs):
....: maximum = probs.max()
....: probsnew = probs/maximum
....: return probsnew
....:
In [51]: %timeit func1(probs)
The slowest run took 229.79 times longer than the fastest. This could mean that an intermediate result is being cached
1000 loops, best of 3: 279 µs per loop
In [52]: %timeit func1(probs)
1000 loops, best of 3: 278 µs per loop
In [53]: %timeit func2(probs)
The slowest run took 356.45 times longer than the fastest. This could mean that an intermediate result is being cached
10000 loops, best of 3: 81 µs per loop
In [54]: %timeit func1(probs)
1000 loops, best of 3: 278 µs per loop
In [55]: %timeit func2(probs)
10000 loops, best of 3: 81.5 µs per loop
numpy方法只需要列表理解的1/3。
使用numpy.array()
转换作为func2的一部分的定时测试(在上面的示例中) -
In [60]: probslist = [p for p in probs]
In [61]: def func2(probs):
....: probsnp = np,array(probs)
....: maxprobs = probsnp.max()
....: probsnew = probsnp/maxprobs
....: return probsnew
....:
In [65]: %timeit func1(probslist)
1000 loops, best of 3: 212 µs per loop
In [66]: %timeit func2(probslist)
10000 loops, best of 3: 198 µs per loop
In [67]: probs = ndr.random_sample(60000)
In [68]: probslist = [p for p in probs]
In [74]: %timeit func1(probslist)
100 loops, best of 3: 11.5 ms per loop
In [75]: %timeit func2(probslist)
100 loops, best of 3: 5.79 ms per loop
In [76]: %timeit func1(probslist)
100 loops, best of 3: 11.4 ms per loop
In [77]: %timeit func2(probslist)
100 loops, best of 3: 5.81 ms per loop
似乎使用numpy数组仍然要快一点。