Быстрое создание условий взаимодействия без SKLearn - PullRequest
0 голосов
/ 14 июля 2020

Я использую следующий код для создания условий взаимодействия в моих данных:

def Interaction(x):
  for k in range(0,x.shape[1]-1):
    for j in range(k+1,x.shape[1]-1):
      new = x[:,k] * x[:,j]
      x = np.hstack((x,new[:,None]))
  return x

Моя проблема в том, что он очень медленный по сравнению с PolynomialFeatures SKLearn. Как мне его ускорить? Я не могу использовать SKLearn, потому что я хотел бы сделать несколько настроек. Например, я хотел бы создать переменную взаимодействия X1 * X2, но также X1 * (1-X2), et c.

1 Ответ

1 голос
/ 14 июля 2020

Мы должны умножить каждый элемент каждой строки попарно, мы можем сделать это как np.einsum('ij,ik->ijk, x, x). Это в 2 раза больше, но все же в 2 раза быстрее, чем PolynomialFeatures.

import numpy as np

def interaction(x):
    """
    >>> a = np.arange(9).reshape(3, 3)
    >>> b = np.arange(6).reshape(3, 2)
    >>> a
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
    >>> interaction(a)
    array([[ 0,  1,  2,  0,  0,  2],
           [ 3,  4,  5, 12, 15, 20],
           [ 6,  7,  8, 42, 48, 56]])
    >>> b
    array([[0, 1],
           [2, 3],
           [4, 5]])
    >>> interaction(b)
    array([[ 0,  1,  0],
           [ 2,  3,  6],
           [ 4,  5, 20]])
    """
    b = np.einsum('ij,ik->ijk', x, x)
    m, n = x.shape
    axis1, axis2 = np.triu_indices(n, 1)
    axis1 = np.tile(axis1, m)
    axis2 = np.tile(axis2, m)
    axis0 = np.arange(m).repeat(n * (n - 1) // 2)
    return np.c_[x, b[axis0, axis1, axis2].reshape(m, -1)]

Сравнение производительности:

c = np.arange(30).reshape(6, 5)
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(2, interaction_only=True)
skl = poly.fit_transform
print(np.allclose(interaction(c), skl(c)[:, 1:]))
# True


In [1]: %timeit interaction(c)
118 µs ± 172 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [2]: %timeit skl(c)
243 µs ± 4.69 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...