Алексей Патрашов
Итог: 4 * 2 * 5 * 5 * 5 = 1000 конечных точек.
Зададимся множеством возможных ответов НИП: откроет, не откроет и пошлёт.
Если у тебя тысяча точек всё равно приводит к трём вариантам, то какой практический смысл во всех вышеприведённых вычислениях и рассуждениях?
alexyecu_wox2team
> Если у тебя тысяча точек всё равно приводит к трём вариантам, то какой практический смысл во всех вышеприведённых вычислениях и рассуждениях?
Это не у меня, это я для деревьев считал. У меня заработала программа — теперь можно самому всё посмотреть и попробовать. Вот, что у нас решалось, первое: матрица функций.
\(G = \left|\matrix{
c_{1} + a_{1} \cdot sin(\frac{\pi \left( x-b_{1} \right)}{12}) \cr
c_{2} + a_{2} \cdot sin(\frac{\pi \left( x-b_{2} \right)}{12}) \cr
c_{3} + a_{3} \cdot sin(\frac{\pi \left( x-b_{3} \right)}{12}) \cr
}\right|\)
Здесь почти всё, как было, только добавилась постоянная и смещение ушло за скобки. Данные https://gamedev.ru/code/forum/?id=285063&m=5939211#m8 отсюда. Код на Python под спойлером.
1Man1
Вот вывод итогов.
Параметры функций для матрицы [[4.999999999999999, 8.100000000000003, 5]] [[-0.4999999999999998, 8.600000000000001, 0.700000000000001]] [[0.09999999999999992, 9.999999999999996, 0.20000000000000104]] Итоговые вероятности [[0.09601654 0.8321138 0.07186966] [0.88240887 0.09267825 0.02491288] [0.95180746 0.01956718 0.02862536] [0.79668207 0.156366 0.04695192]] Отклонения вероятностей [[-0.00398346 -0.0178862 0.02186966] [-0.01759113 -0.00732175 0.02491288] [ 0.00180746 -0.03043282 0.02862536] [-0.00331793 0.006366 -0.00304808]] Сумма квадратов отклонений вероятностей 0.0036074338942218044
Видно, что погрешность не превышает примерно 3% для взятых из пальца исходных данных.
Алексей Патрашов
> Это не у меня, это я для деревьев считал
А для матриц сколько вариантов входных данных для обучения?
1Man1
> А для матриц сколько вариантов входных данных для обучения?
От одного до бесконечности. Это аппроксимация данных кривой: она тем точнее, чем больше данных. Причём по матрицам ещё и графики можно построить и посмотреть, не завалилась ли кривая куда не надо. Вот пример уже для двух видов исходных данных: время суток и отношение к игроку. Основной код под спойлером, а здесь только данные.
Вот исходные данные.
Pc = np.array([[90, 10, 0], [90, 10, 0], [90, 10, 0], [90, 10, 0],
[ 5, 65, 25], [75, 25, 0], [85, 10, 5], [80, 15, 5],
[ 5, 15, 80], [25, 50, 25], [50, 35, 15], [20, 50, 30]]) / 100Вот по ним посчитаны параметры, а по параметрам посчитаны отклонения.
[[5.699999999999997, 11.099999999999993, 5], [8.499999999999988, 1.9000000000000008]] [[-0.4999999999999998, 1.000000000000015, 1.100000000000001], [-0.30000000000000004, 0.5]] [[-0.40000000000000013, 2.5000000000000164, 0.400000000000001], [-1.6000000000000014, 0.2999999999999999]] [[88.5 11.6 -0.1] [89.2 11.3 -0.5] [89. 11. -0. ] [88.4 11.3 0.3] [10.5 63.5 26. ] [75.1 24.8 0.1] [84.5 11.6 3.9] [77.4 14.9 7.7] [14.3 41.4 44.2] [18.9 39.4 41.7] [32.2 33.3 34.6] [29. 34.7 36.4]] [[ -1.49 1.64 -0.15] [ -0.82 1.31 -0.48] [ -0.97 1.01 -0.04] [ -1.58 1.31 0.27] [ 0.46 -1.46 1. ] [ 0.1 -0.22 0.13] [ -0.45 1.58 -1.12] [ -2.6 -0.13 2.73] [ 9.34 26.44 -35.78] Выброс! [ -6.12 -10.56 16.68] Выброс! [-17.81 -1.75 19.56] Выброс! [ 8.96 -15.33 6.37]] Выброс! 0.35878727310572556 0.3578556997231728
По этим отклонениям сразу видно, что исходные данные для последних четырёх случаев были взяты слишком далеко и не вписываются в общий набор данных. Исправляем данные.
Pc = np.array([[80, 15, 5], [90, 10, 0], [90, 10, 0], [80, 15, 5],
[25, 55, 20], [75, 25, 0], [85, 15, 0], [45, 40, 15],
[15, 55, 30], [20, 50, 30], [25, 50, 25], [20, 50, 30]]) / 100По ним получаем новые параметры и отклонения.
[[2.8000000000000016, 11.59999999999999, 5], [7.79999999999999, 1.9000000000000008]] [[-3.6000000000000014, 5.900000000000011, 3.7000000000000033], [-2.1000000000000005, 0.7999999999999999]] [[-1.7000000000000006, 6.000000000000011, 1.200000000000001], [-1.6000000000000014, 0.3999999999999999]] [[81.6 14.3 4. ] [87.7 10.3 2. ] [88. 10.1 1.9] [82.2 13.9 3.9] [24.8 54.2 21.1] [74.9 25.2 -0. ] [85.5 14.6 -0. ] [43.7 40.8 15.5] [16.6 53.6 29.8] [19.1 51.5 29.3] [24. 48.5 27.5] [21.1 50.8 28.2]] [[ 1.65 -0.67 -0.98] [-2.3 0.35 1.95] [-1.96 0.08 1.88] [ 2.19 -1.07 -1.12] [-0.24 -0.83 1.06] [-0.13 0.17 -0.05] [ 0.47 -0.45 -0.02] [-1.3 0.78 0.52] [ 1.55 -1.38 -0.17] [-0.86 1.51 -0.65] [-1.03 -1.49 2.52] [ 1.06 0.79 -1.85]] 0.005540276932853045
Где-то я пропустил новую матрицу для учёта ещё и отношения к игроку.
\(G = \left|\matrix{
c_{1} + a_{1} \cdot sin(\frac{\pi \left( x-b_{1} \right)}{12}) & u_{1} \cdot x + v_{1} \cdot x^{2} \cr
c_{2} + a_{2} \cdot sin(\frac{\pi \left( x-b_{2} \right)}{12}) & u_{2} \cdot x + v_{2} \cdot x^{2} \cr
c_{3} + a_{3} \cdot sin(\frac{\pi \left( x-b_{3} \right)}{12}) & u_{3} \cdot x + v_{3} \cdot x^{2} \cr
}\right|\)
Переходим к исправлению более сложных ошибок. Первым делом проверяем вероятности не только в трёх точках, а по всему множеству значений, например, отношения к игроку.
XX = list(map(lambda x: [3, x], range(-5,6))) XX [[3, -5], [3, -4], [3, -3], [3, -2], [3, -1], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [3, 5]] np.set_printoptions(precision=1, suppress=True) print(P(G, XX) * 100, '\n') [[ 16.6 53.6 29.8] [ 4.5 61.4 34.1] [-12.9 72.9 40. ] Уход в минус! [-33.2 87. 46.2] Уход в минус! [-29.6 87.3 42.3] Уход в минус! [ 24.8 54.2 21.1] [ 67.3 26.2 6.5] [ 81.3 16.2 2.5] [ 84. 13.7 2.3] [ 83.2 13.7 3.1] [ 81.6 14.3 4. ]]
Видим, что у нас произошёл уход в минус и надо ставить преобразующую функцию F, которая сделает все отрицательные значения положительнвми.
def F(X):
return (np.tanh((X - 100) / 50) + 1) * 50Теперь вероятности не уходят в минус и посте поправок в исходных данных мы получаем более приемлемые значения.
Pc = np.array([[80, 15, 5], [90, 10, 0], [90, 10, 0], [85, 15, 0],
[25, 40, 35], [50, 25, 25], [60, 25, 15], [35, 35, 30],
[10, 50, 40], [20, 50, 30], [25, 50, 25], [15, 55, 30]]) / 100Проверяем то же самое.
XX = list(map(lambda x: [3, x], range(-5,6))) np.set_printoptions(precision=1, suppress=True) print(P(G, XX) * 100, '\n') [[ 9.2 52.1 38.7] [10.1 45.6 44.3] [11.7 41.1 47.2] [14.4 38.5 47.2] [18.7 37.2 44.1] [25.5 36.6 37.9] [35.2 35.7 29.1] [47.4 33.4 19.2] [60.5 28.9 10.6] [72.2 23. 4.9] [81.1 17. 1.9]]
Видим, что вероятности не уходят в минус и почти все правильно увеличиваются и уменьшаются. То же самое можно проверить и для другого времени. Посмотрим ещё раз на полученные результаты.
[[10.79999999999998, 7.700000000000005, 5], [6.599999999999994, 0.5000000000000001]] [[-6.099999999999994, 6.20000000000001, -0.499999999999999], [-1.9000000000000006, 0.2]] [[-10.299999999999981, 7.900000000000004, -4.999999999999997], [-6.699999999999994, -1.1]] [[81.1 17. 1.9] [90.9 8.3 0.8] [92.8 6.7 0.5] [85. 13.8 1.2] [25.5 36.6 37.9] [47.2 28.1 24.7] [56.8 25.8 17.5] [33.8 36.8 29.5] [ 9.2 52.1 38.7] [20.7 48.7 30.6] [27.4 48.9 23.8] [12.9 55.3 31.9]] [[ 1.11 2.02 -3.13] [ 0.92 -1.69 0.77] [ 2.85 -3.32 0.48] [ 0.02 -1.19 1.17] [ 0.51 -3.37 2.86] [-2.8 3.14 -0.34] [-3.22 0.76 2.46] [-1.24 1.78 -0.54] [-0.83 2.1 -1.27] [ 0.67 -1.3 0.63] [ 2.36 -1.14 -1.22] [-2.15 0.27 1.88]] 0.012704621824843427
Представляет интерес вот эта часть.
[[10.79999999999998, 7.700000000000005, 5], [6.599999999999994, 0.5000000000000001]] [[-6.099999999999994, 6.20000000000001, -0.499999999999999], [-1.9000000000000006, 0.2]] [[-10.299999999999981, 7.900000000000004, -4.999999999999997], [-6.699999999999994, -1.1]]
Видно, что коэффициенты для первой и второй степени отношения к игроку для согласия и посылания одного знака, что показывает правильную тенденцию, а для средней реакции они разного знака и меньшего значения, то есть на среднюю реакцию отношение влияет меньше, чем на крайние, что соответствует здравому смыслу.
Алексей Патрашов
> вычисление коэффициетов a, b, c, d, u и v, которых может быть гораздо больше.
У Вас, как обычно, очень высокий педагогический талант, поэтому лично я не понял, зачем их вычислять - когда их можно и нужно задавать. При чём задаваться они могут не просто для класса NPC, а даже индивидуально (рандомно или вручную).
> В целом этот способ из области «круто, но трудно».
А в чём собсно вопрос сабжа? "Есть такой инструмент - матрицы" ?
GDR
> У Вас, как обычно, очень высокий педагогический талант
Я по специальности расчётчик-программист, поэтому переговорные и педагогические способности в число моих достоинств не входят — приходится довольствоваться тем, что есть.
GDR
> я не понял, зачем их вычислять - когда их можно и нужно задавать
Их действительно можно и нужно задавать, но нам же не надо посчитать просто что-то, нам надо попасть в определённую цель: пройти как можно ближе к заданным точкам. Если заданных точек нет, можно просто задавать коэффициенты и смотреть, что получается, но это более простая задача и она как бы изначально уже решена. Гораздо важнее задача, в которой надо сначала определить неизвестные коэффициенты, а потом уже ими управлять, как захочется. Эта задача встречается чаще и она сложнее задачи просто посчитать, ни на что не ориентируясь.
GDR
> А в чём собсно вопрос сабжа? "Есть такой инструмент - матрицы" ?
Он даже не просто есть, а для него написано множество утилит и библиотек. Матрицы настолько хорошо изучены и для них столько всего написано, что можно брать сразу почти готовое и сразу делать задачу, а не писать из головы очередную библиотеку или утилиту, не имея ни образцов, ни примеров, а потом гадать, правильно или неправильно получилось. А тут пример из области "Любая задача уже имеет решение на Фортране".
1Man1
> P.S. Нейросеть то попроще, там только веса регулируешь
Теперь и здесь можно регулировать степень влияния исходных данных от 0 до 100%.
ЯННП, но очень интересно... (с)
P.S. Нейросети придуманы и используются очень давно, задолго до нынешнего хайпа.
GDR
> Нейросети придуманы и используются очень давно, задолго до нынешнего хайпа.
А матрицы придуманы много сотен лет назад. Но мне кажется, что строить функцию нейросетью это перебор по расходам.
А матрицы придуманы много сотен лет назад. Но мне кажется, что строить функцию нейросетью это перебор по расходам.
Зависит от задач.
Если узкое направление, то стоит писать быстрый и не сложный алгоритм.
А если спектр задач большой, то юзать нейронку, например свой аналог чатGpt.
строить функцию нейросетью это перебор по расходам.
Да расход будет большой, но и спектр задач тоже.
Modern ai жрут много памяти от 8 гиг и до 128 гиг.
Потому что строят функции нейросетью, а для каждой надо килобайты памяти.
А функций много и нейронов миллиарды, вот это всё и жрет память.
Алексей Патрашов
> Раньше эту технологию не могли осилить потому, что не было достаточно мощных ЭВМ для решения задачи оптимизации. Потом не могли осилить потому, что не могли осилить раньше и забыли. А потом начали молиться на нейросети.
Чувствуется эффект Даннинга-Крюгера)))
Уж за десятки лет игровой индустрии, студии, наверное бы, уже догадались посадить инженеров и плотно изучить вопросы взаимодействия с NPC и их реакции на эти взаимодействия.
Крупные игроки рынка держат в штате десятки юристов и десятки экономистов для решения самых разных задач, а списать пару сотен тысяч долларов в год еще и на парочку инженеров, чтобы посадить их на ресеч этой темы как-то не удосужились, подзабыли, видимо)))
Storm54
> Чувствуется эффект Даннинга-Крюгера
Не без этого, но за время работы на самоокупающихся предприятиях я убедился, что никто не хочет внедрять ничего нового, поднимая риски потери денег и взваливая на себя ответственность. Заменить оборудование или станки столетней давности экономически понятно, заменять программы или скрытые в них алгоритмы — уже никому не понятно. Есть настольные игры с уже понятными всем правилами вычисления поведения и эти правила понятны. Дизайнер может считать всё в электронной таблице и от него не требуется понимание высшей математики. Настолькные игры хорошо продаются и сделанные по ним компьютерные игры будут хорошо продаваться.
Здесь требуется понимание высшей математики, значит уже не любой дизайнер может пользоваться этой технологией. Требуется хоть немного знать програмирование — снова рост зарплаты у дизайнеров и ограничения по применению. Пока не будут сделаны библиотеки, утилиты и графические приложения для быстрого и лёгкого применения средства, оно будет иметь чисто научное применение.
Алексей Патрашов
> [[10.79999999999998, 7.700000000000005, 5], [6.599999999999994, 0.5000000000000001]]
> [[-6.099999999999994, 6.20000000000001, -0.499999999999999], [-1.9000000000000006, 0.2]]
> [[-10.299999999999981, 7.900000000000004, -4.999999999999997], [-6.699999999999994, -1.1]]
>
> [[81.1 17. 1.9]
> [90.9 8.3 0.8]
> [92.8 6.7 0.5]
> [85. 13.8 1.2]
> [25.5 36.6 37.9]
> [47.2 28.1 24.7]
> [56.8 25.8 17.5]
> [33.8 36.8 29.5]
> [ 9.2 52.1 38.7]
> [20.7 48.7 30.6]
> [27.4 48.9 23.8]
> [12.9 55.3 31.9]]
>
> [[ 1.11 2.02 -3.13]
> [ 0.92 -1.69 0.77]
> [ 2.85 -3.32 0.48]
> [ 0.02 -1.19 1.17]
> [ 0.51 -3.37 2.86]
> [-2.8 3.14 -0.34]
> [-3.22 0.76 2.46]
> [-1.24 1.78 -0.54]
> [-0.83 2.1 -1.27]
> [ 0.67 -1.3 0.63]
> [ 2.36 -1.14 -1.22]
> [-2.15 0.27 1.88]]
Вот это вот - вообще ни о чем не говорит. Числа и числа. Такое можно получить генератором случайных чисел.
Давай практический наглядный результат. Пусть даже в виде текстовой рпг/квеста. Чтобы мы на практике могли оценить то, как принимает решения твой НИП. И почему у тебя РПГ, но НИП, а не НПЦ?
MrShoor
> почему у тебя РПГ
ручной противотанковый гранатомет
Storm54
> Уж за десятки лет игровой индустрии, студии, наверное бы, уже догадались посадить инженеров и плотно изучить вопросы взаимодействия с NPC и их реакции на эти взаимодействия.
Вот и пришёл ответ на вопрос, почему они этого не сделали до сих пор. Даже долго ждать не пришлось.
MrShoor
> Вот это вот - вообще ни о чем не говорит. Числа и числа. Такое можно получить генератором случайных чисел.
Вот это самый обычный ответ менеджера или директора, которому показывают любое научное достижение. Нам нужны бизнес, экономика, менеджмент, финансы, KPI, продажи — это мы понимаем. Вот когда оно будет приносить прибыль, мы этим будем заниматься. Поэтому придётся ждать, пока у меня время появится, чего не будет, или пока не найдётся желающий попробовать в своём учебном пректе новую технологию.
Тема в архиве.