numpy数据分析

作者: 与尔岩说 | 来源:发表于2017-08-26 20:29 被阅读0次

Second part of post: numpy tips and tricks 2
I used example from histogram equalization with numpy
Numpy log-likelihood benchmark

Argsort

根据一列的信息来对另一列排序

比如要对人根据身高进行排序

ages = np.random.randint(low=30, high=60, size=10)
heights = np.random.randint(low=150, high=210, size=10)
sorter = np.argsort(ages)
print(ages[sorter])
print(heights[sorter])

根据生成的索引进行排序

permutation = np.random.permutation(10)
original = np.array(list('abcdefghij'))

print(permutation)
print(original)
print(original[permutation])
[1 7 4 9 2 8 0 5 6 3]
['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j']
['b' 'h' 'e' 'j' 'c' 'i' 'a' 'f' 'g' 'd']

逆向排序

inverse_permutation = np.argsort(permutation)

print(original[permutation][inverse_permutation])
['a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j']

计算排名

data = np.random.random(10)

print(data)
print(np.argsort(np.argsort(data)))

from scipy.stats import rankdata
rankdata(data) - 1

分布平滑

写一个单调的变换可以使得我们把一个分布变为均匀分布等等,这种方法在比较两个分布的时候是很常见的,尤其是那种有着奇怪的形状和尾巴的。


class IronTransform:
    def fit(self, data, weights):
        weights = weights / weights.sum()
        sorter = np.argsort(data)
        self.x = data[sorter]
        self.y = np.cumsum(weights[sorter])
        return self
        
    def transform(self, data):
        return np.interp(data, self.x, self.y)
sig_pred = np.random.normal(size=10000) + 1
bck_pred = np.random.normal(size=10000) - 1
from matplotlib import pyplot as plt
plt.figure()
plt.hist(sig_pred, bins=30, alpha=0.5)
plt.hist(bck_pred, bins=30, alpha=0.5)
plt.show()
image.png

在转换后:

image.png

这个函数也可以用来做直方图均衡化,这是图像处理当中调整对比度的方法。

from PIL import Image
image = np.array(Image.open('AquaTermi_lowcontrast.jpg').convert('L'))
flat_image = image.flatten()
result = IronTransform().fit(flat_image, weights=np.ones(len(flat_image))).transform(image)

plt.figure(figsize=[14, 7])
plt.subplot(121), plt.imshow(image, cmap='gray'), plt.title('original')
plt.subplot(122), plt.imshow(result, cmap='gray'), plt.title('after histogram equalization')
plt.show()
image.png

值得一提的是,当处理过大或者过小的数字的时候可以用numpy.clip

np.clip([-100, -10, 0, 10, 100], a_min=-15, a_max=15)
array([-15, -10,   0,  10,  15])

x = np.arange(-5, 5)
print(x)
print(x.clip(0))

[-5 -4 -3 -2 -1  0  1  2  3  4]
[0 0 0 0 0 0 1 2 3 4]

Broadcasting, numpy.newaxis

有权重的协方差矩阵

data = np.random.normal(size=[100, 5])
weights = np.random.random(100)
def covariation(data, weights):
    weights = weights / weights.sum()
    return data.T.dot(weights[:, np.newaxis] * data)
covariation(data, np.ones(len(data)))

也可以通过这种方法:

np.einsum('ij, ik, i -> jk', data, data, weights / weights.sum())

计算两个向量之间的距离

X = np.random.normal(size=[1000, 100])
distances = ((X[:, np.newaxis, :] - X[np.newaxis, :, :]) ** 2).sum(axis=2) ** 0.5
products = X.dot(X.T)
distances2 = products.diagonal()[:, np.newaxis] + products.diagonal()[np.newaxis, :]  - 2 * products
distances2 **= 0.5

也可以使用包包

from sklearn.metrics.pairwise import pairwise_distances
distances_sklearn = pairwise_distances(X)

np.allclose(distances, distances_sklearn), np.allclose(distances2, distances_sklearn)

Unique

类别变量转换

类似于labelencoder的功能,能很快的把他进行类别的编码

unique_categories, new_categories = np.unique(categories, return_inverse=True)

当我们需要检测是否在一个list中的时候可以用这个命令

np.in1d(['ab', 'ac', 'something new'], unique_categories)

处理缺失情况

class CategoryMapper:
    def fit(self, categories):
        self.lookup = np.unique(categories)
        return self
        
    def transform(self, categories):
        """Converts categories to numbers, 0 is reserved for new values (not present in fitted data)"""
        return (np.searchsorted(self.lookup, categories) + 1) * np.in1d(categories, self.lookup) 
CategoryMapper().fit(categories).transform([unique_categories[0], 'abc'])

percentile

edges = np.percentile(x, np.linspace(0, 100, 20))
_ = plt.hist(x, bins=edges, normed=True)

除了onehot编码,对于类别变量来说还有很多的技巧比如,我们可以将每一个变量的值替换成这个值在数据中出现的次数

np.bincount(new_categories)[new_categories]

另一个技巧就是在这里将值替换成每一个事件的预测的可能性,这个是更加复杂的技巧,因为我们需要对于这个增加一些权重。

predictions = np.random.normal(size=len(new_categories))

means_over_category = np.bincount(new_categories, weights=predictions) / np.bincount(new_categories)
means_over_category[new_categories]

同样的技巧,如果我们想测度数据的偏差程度的话:

means_of_squares_over_category = np.bincount(new_categories, weights=predictions**2) / np.bincount(new_categories)
var_over_category = means_of_squares_over_category - means_over_category ** 2
var_over_category[new_categories]

unfunc

进一步的说,我们可以通过一系列的二元函数来做,比如:
numpy.add, numpy.subtract, numpy.multiply, numpy.maximum, numpy.minimum
在下面的例子中我们会用ufunc.at

max_over_category = np.zeros(new_categories.max() + 1) - np.infty
np.maximum.at(max_over_category, new_categories, predictions)

print(max_over_category[new_categories])

当我们需要计算每一个组合的次数的时候,通常有两种方法,可以将一系列的变量变成一个,比如:feature1 * (numpy.max(feature2) + 1) + feature2
在比如做一个多维度的表格。

first_category = np.random.randint(0, 100, len(new_categories))
second_category = np.random.randint(0, 100, len(new_categories))

counters = np.zeros([first_category.max() + 1, second_category.max() + 1])
np.add.at(counters, [first_category, second_category], 1)

现在我们可以用colected 统计来做一点有用的事情

counters[first_category, second_category]

# occurences of second category
counters.sum(axis=0)[second_category]
# maximal occurences of second category with same value of first category
counters.max(axis=0)[second_category]
# number of occurences of second category with fixed first category:
counters[42, second_category]

计算ROC曲线

你可以用sklearn.metrics.roc_curve来实现。roc曲线爆款三个输入变量,首先是她的label(二元0或者1),预测(真实值)以及权重


def roc_curve(labels, predictions, sample_weight):
    sig_weights = sample_weight * (labels == 1)
    bck_weights = sample_weight * (labels == 0)
    thresholds, predictions = np.unique(predictions, return_inverse=True)
    tpr = np.bincount(predictions, weights=sig_weights)[::-1].cumsum()
    fpr = np.bincount(predictions, weights=bck_weights)[::-1].cumsum()
    tpr /= tpr[-1]
    fpr /= fpr[-1]
    return fpr, tpr, thresholds[::-1]

或者

# sometimes sklearn adds one more element to all arrays.
# I have no idea why this is needed and when, but in this case all answers turn to False
from sklearn.metrics import roc_curve as sklearn_roc_curve
fpr2, tpr2, thr2 = sklearn_roc_curve(labels, predictions, sample_weight=weights)
np.allclose(fpr1, fpr2), np.allclose(tpr1, tpr2), np.allclose(thr1, thr2)

有权重的Kolmogorov-Smironv distace

roc 去显示一个重要的在机器学习领域很重要的工具因为它可以比较有序的信息针对原来的分布
接下来我们来计算基于ROC的KS
ks=max|F1(x)-F2(X)|


def ks_2samp(distribution1, distribution2, weights1, weights2):
    labels = np.array([0] * len(distribution1) + [1] * len(distribution2))
    predictions = np.concatenate([distribution1, distribution2])
    weights = np.concatenate([weights1, weights2])

    fpr, tpr, _ = roc_curve(labels, predictions, sample_weight=weights)
    return np.max(np.abs(fpr - tpr))

相关文章

  • Python 数据分析学习笔记: numpy 篇

    Python 数据分析学习笔记:numpy篇 前言 数据分析的主要库是 pandas,而 numpy 是 pand...

  • 优达学城--机器学习入门

    第4部分:数据分析基础 4.4 使用numpy和pandas分析数据 += 与 +的区别: 4.4 使用numpy...

  • 97、NumPy基础

    NumPy是高性能科学计算和数据分析的基础包 NumPy在数据分析中常用的功能: 1、用于数据整理和清理、...

  • Python科学计算相关

    科学计算NumPy & SciPy: http://www.numpy.org/ 数据分析Pandas:http:...

  • day77-数据分析之numpy

    numpy是数据分析中最基础的分析库,而numpy中最重要的部分是np.array 1numpy库 1.1利用数组...

  • Python实现数据分析1

    Python-数据分析常用库 1)Numpy 2) Pandas 3) Matplotlib Numpy 基于数组...

  • 数据挖掘 numpy,pandas库详解

    python依靠numpy和pandas成为数据挖掘的首选语言,就连c++也排名其后,numpy分析数据,pand...

  • numpy、pandas基础

    数据分析基础知识点 -- numpy and Pandas 1.numpy: 适合处理统一的数值数组数据 -- n...

  • Python机器学习库

    NumPy库 用于高性能科学计算和数据分析,是常用的高级数据分析库的基础包​Mac安装numpy库:直接在终端通过...

  • 数据分析挖掘常用模块

    1.numpy--数组操作,后续的许多包都依赖numpy 2.pandas ---数据探索和数据分析 3.matp...

网友评论

    本文标题:numpy数据分析

    本文链接:https://www.haomeiwen.com/subject/uqbmdxtx.html