Как ускорить анализ чувствительности? - PullRequest
0 голосов
/ 09 апреля 2019

Мне приходится иметь дело с анализом чувствительности, который необходимо ускорить. Данные приведены в виде массива, назовем его A. A получил форму (M, N), где M - это количество точек данных, а N - это количество атрибутов, из которых состоит каждая точка данных, и по которым должен быть выполнен анализ. Для простоты предположим M=2, N=4. Имейте в виду что-то вроде M=1+e9. Тем не мение. Пусть a_{mn} будет элементом A. Анализ должен выполняться для вычисления функции f(a_{m1},a_{m2}, a_{m3}, a_{m4}) = a_{m1} - a_{m2} - ( a_{m3} * a_{m4} ) для каждой строки, чтобы f(A) приводил к массиву B shape (M,1). Так что b_m является элементом B.

Хотите создать массив E shape (M, N), содержащий чувствительность для каждого элемента на B в общей сложности. например элемент e: m=1 an n=2, e_{mn}= e_{12} = f(a_{11},a_{12}*(1-i), a_{13}, a_{14}) - b_1

Теперь ищем чувствительность каждого элемента на B. Пусть чувствительность i будет i=0.05. Прежде всего я вычислил массив формы (M, N), который содержит все элементы и их изменения. Давайте назовем это C = B * i, где * - это поэлементное умножение. После этого, создав D, я перебрал все элементы массива. Наконец вычитается B, чтобы получить E. Я думаю, это слишком дорого и очень глупо. Вот почему он не работает с огромным количеством данных. Вот что я получил:

import numpy as np

A = np.array([
    [2., 2., 100., 0.02],
    [4., 2., 100., 0.02]
])

def f_from_array(data):
    att_1 = data[:, 0]
    att_2 = data[:, 1]
    att_3 = data[:, 2]
    att_4 = data[:, 3]
    return ((att_1 - att_2) - (att_3 * att_4)).reshape(-1, 1)

def f_from_list(data):
    att_1 = data[0]
    att_2 = data[1]
    att_3 = data[2]
    att_4 = data[3]
    return ((att_1 - att_2) - (att_3 * att_4)).reshape(-1, 1)

B = f_from_array(A)

# B = np.array([
#     [-2.],
#     [0.]
# ])

i = 0.05
C = A * i
A_copy = A * 1
D = np.zeros(A.shape)
for m in range(A.shape[0]):
    for n in range(A.shape[1]):
        A_copy[m][n] -= C[m][n]
        D[m][n] = f_from_list(A_copy[m])
        A_copy = A * 1

E = D - B
E = np.sqrt(E**2)

Выход:

E = np.array([
    [0.1, 0.1, 0.1, 0.1],
    [0.2, 0.1, 0.1, 0.1]
])

1 Ответ

0 голосов
/ 09 апреля 2019

Очевидно, что проблемной частью вашего кода является вложенный цикл.Здесь многое можно сделать, и, вероятно, можно полностью устранить цикл.

Но, не слишком задумываясь о том, что делает код, наиболее очевидным фактором, убивающим время, является, вероятно, создание целой копии.массив во время каждой итерации цикла .Устраните это, просто восстановив один элемент вместо всего массива.

Вместо

A_copy = A * 1

внутри цикла, сделайте следующее:

A_copy[m, n] = A[m, n]

(КакКроме того: индексирование через запятую выполняется немного быстрее, чем многоэтапное индексирование с несколькими парами скобок, но, вероятно, оно будет незначительным для вашего случая.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...