Передний груз и Задний груз | График нормального распределения и S-кривые в Excel - программирование
Подтвердить что ты не робот

Передний груз и Задний груз | График нормального распределения и S-кривые в Excel

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


Распределение с фронтальной загрузкой: как показано ниже, оно имеет быстрый старт. Например, в проекте, когда предполагается, что в начале проекта потребляется больше ресурсов, затраты/часы распределяются агрессивно в начале проекта. Front-Loaded Distribution / S Curve


Распределение с задней загрузкой: В отличие от распределения с фронтальной загрузкой, оно начинается с более низкого наклона и становится все более крутым к концу проекта. Например, когда большинство ресурсов предполагается использовать в конце проекта. Rear Load Distribution S Curve

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


Для справки я приведу диаграмму кривой Белла/стандартное нормальное распределение (когда Среднее = Медиана) (ниже) и соответствующую формулу для начала. Normal Distribution S Curve


Постановка задачи: мне удалось сгенерировать кривую нормального распределения (см. Формулы ниже), однако я не могу найти решение для кривых с фронтальной или обратной загрузкой.

Как вывести асимметрию вправо (распределение с фронтальной загрузкой/положительным перекосом, что означает, что среднее больше, чем медиана) и левое наклонение (распределение с обратной загрузкой/отрицательно скошенным, что означает, что среднее меньше медианы) в нормальном распределении?

Gaussian Bell Curve with Excel Formula

Формула объяснила:

Ячейка B8 обозначает произвольно выбранное стандартное отклонение. Влияет на эксцесс нормального распределения. На приведенном выше снимке экрана я выбираю диапазон нормального распределения от -3SD до 3SD.

Ячейки с B9 по B18 обозначают равномерное распределение Z-показателя по формуле:

=B8-((2*$B$8)/Period)

Ячейки C9-C18 обозначают нормальное распределение на основе Z Score и Суммы с использованием формулы:

=(NORMSDIST(B9)-NORMSDIST(B8))*Amount/(1-2*NORMSDIST($B$8))

Обновление: Перейдя по одной из ссылок в комментариях, я ближе всего попал в следующую ситуацию. Проблема выделена желтым узором, поскольку из-за использования функции volatile Rand() графики не являются гладкими, как должно быть. Поскольку моя формула, приведенная выше, не создает шаблон ZigZag, я уверен, что мы могли бы искажать нормальное распределение и сглаживать тоже! ZigZag Columns Issue in Normal Distribution

Замечания:

  1. Я использую Excel 2016, поэтому я рад, если любая новая формула может решить мою проблему. Кроме того, я не стесняюсь использовать UDF.

  2. Числа распределения передней и задней нагрузки условны. Они могут отличаться. Меня интересует только форма получившегося графика.

Пожалуйста, помогите!

4b9b3361

Ответ 1

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

enter image description here

С формулами

enter image description here

Кривая

enter image description here

Заметки:

  1. Если вы хотите изменить ячейки, вы должны перетащить ячейки вниз или вверх, чтобы завершить серию
  2. Если вы хотите изменить общую стоимость, вы можете изменить множитель
  3. Если вы хотите изменить наклон кривой, вы можете изменить делитель в столбце C, который в настоящее время установлен на 2, если он равен -2, угол наклона изменит направление, вы можете поэкспериментировать с другими числами, направление зависит от них меньше нуля или больше нуля

Для копирования прошлого

=A2+180/($G$3-1)
=RADIANS(A2)
=$G$4*SIN(B2 + SIN(B2)/2)

Ответ 2

Я использовал фактические математические формулы, чтобы получить результат. Мне кажется, что вы хотели достичь. Оранжевые ячейки в разделе "Перекошено" - это те, которые можно изменить для изменения степени и направления перекоса. Ниже приведены некоторые рисунки для демонстрации, за которыми следуют используемые формулы.

enter image description here

enter image description here

enter image description here

Формулы в строке 5, столбец

B: =(A5*$A$2)+0 (0 - среднее значение, вы можете изменить, как вам нравится)

C: =(1/($A$2* SQRT(2*PI())))*EXP(-(B5^2)/2)

D: =0.5*(1+ERF(B5/SQRT(2)))

E: =$A$1*C5

F: =(A5*$A$2*(1+$F$2*SIN((F4*PI())/(2*$F$4))))+0 (0 - среднее значение, вы можете изменить как вам нравится)

G: =(1/($A$2* SQRT(2*PI())))*EXP(-((F5+$G$2)^2)/2)

H: =0.5*(1+ERF((B5+$G$2)/SQRT(2)))

I: =$A$1*G5

Ответ 3

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

Изменение среднего значения перемещает пик влево или вправо. Изменение стандартного отклонения делает величины более однородными или более переменными. Я использовал 0-1000 в качестве диапазона по умолчанию в примере ниже, но должно быть легко изменить формулу, чтобы получить любое значение, которое вы хотите. ПРИМЕЧАНИЕ Чтобы выполнить ваше требование о том, что все ячейки должны быть ненулевыми, вам нужно вручную корректировать числа, пока не получите кривую, которая подходит.

Желтые ячейки предназначены для ввода данных, зеленые ячейки - это количество (поэтому, если вы добавите ячейки, они должны быть пронумерованы в соответствии с последовательностью).

normal and skewed distribution examples

Формула в ячейке B7 (скопирована в ячейку B16): =NORMDIST($A7*1000/MAX($A$6:$A$17),$B$3,$B$4,TRUE)-NORMDIST($A6*1000/MAX($A$6:$A$17),$B$3,$B$4,TRUE),

Формула в ячейке C7 (скопирована в ячейку C16): =IF(A7=MAX($A$6:$A$17),$C$5-SUM(C$6:C6),ROUND(B7/SUM($B$7:$B$17)*$C$5,0))

Добавление новых корзин достаточно простое и все еще основано на диапазоне 0-1000, поэтому вам не нужно изменять какие-либо числа, кроме добавления строк и копирования формул:

skewed distribution with more bins

Вышеприведенный пример также показывает, как узкое стандартное отклонение и высокое среднее значение объединяются, чтобы исходные бункеры имели очень небольшое количество. Но есть значение (пока счет достаточно велик).

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

Ответ 4

Если вы открыты для ответа на Python, я могу дать вам код, чтобы получить библиотеку Python Pandas для генерации случайных наблюдений из искаженного нормального элемента, а затем для их сортировки (корзины). Следующее в скрипте Python, которое фиксирует сценарий использования, но также может быть создано с помощью COM и может быть создано из VBA.

import numpy as np
import pandas as pd
from scipy.stats import skewnorm

class PythonSkewedNormal(object):
    _reg_clsid_ = "{1583241D-27EA-4A01-ACFB-4905810F6B98}"
    _reg_progid_= 'SciPyInVBA.PythonSkewedNormal'
    _public_methods_ = ['GeneratePopulation','BinnedSkewedNormal']

    def GeneratePopulation(self,a, sz):
        # https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.seed.html
        np.random.seed(10);
        #https://docs.scipy.org/doc/scipy-0.19.1/reference/generated/scipy.stats.skewnorm.html
        return skewnorm.rvs(a, size=sz).tolist();

    def BinnedSkewedNormal(self,a, sz, bins):
        # https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.seed.html
        np.random.seed(10);
        #https://docs.scipy.org/doc/scipy-0.19.1/reference/generated/scipy.stats.skewnorm.html
        pop = skewnorm.rvs(a, size=sz); #.tolist();
        bins2 = np.array(bins)
        bins3 = pd.cut(pop,bins2)

        table = pd.value_counts(bins3, sort=False)

        table.index = table.index.astype(str)

        return table.reset_index().values.tolist();

if __name__=='__main__':
    print ("Registering COM server...")
    import win32com.server.register
    win32com.server.register.UseCommandLine(PythonSkewedNormal)

И код клиента VBA

Option Explicit

Sub TestPythonSkewedNormal()

    Dim skewedNormal As Object
    Set skewedNormal = CreateObject("SciPyInVBA.PythonSkewedNormal")

    Dim lSize As Long
    lSize = 100

    Dim shtData As Excel.Worksheet
    Set shtData = ThisWorkbook.Worksheets.Item("Sheet3") '<--- change sheet to your circumstances
    shtData.Cells.Clear

    Dim vBins
    vBins = Array(-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5)

    'Stop
    Dim vBinnedData
    vBinnedData = skewedNormal.BinnedSkewedNormal(-5, lSize, vBins)

    Dim rngData As Excel.Range
    Set rngData = shtData.Cells(2, 1).Resize(UBound(vBins) - LBound(vBins), 2)

    rngData.Value2 = vBinnedData

    'Stop

End Sub

Образец вывода

(-5, -4]        0
(-4, -3]        0
(-3, -2]        4
(-2, -1]       32
(-1, 0]        57
(0, 1]          7
(1, 2]          0
(2, 3]          0
(3, 4]          0
(4, 5]          0

Оригинальный код хранится в моем блоге