Python для моделирования и анализа случайных событий: жребий и полная группа
Запись от nikulinn_artyomm размещена 22.01.2024 в 20:45
Показов 1477
Комментарии 0
|
В этом блоге я хочу поделиться с вами результатами моей работы над интересным проектом, где я использовал [B]Python[/B] для моделирования и анализа случайных событий. Мы рассмотрим два различных типа моделирования: [B]жребий с равновероятными исходами[/B] и [B]полную группу случайных событий с заданными вероятностями[/B]. [B][SIZE="4"]Жребий с равновероятными исходами[/SIZE][/B] Представьте, что у вас есть 10 одинаковых монет, и вы хотите узнать, какая из них выпадет, если вы бросите их одновременно. Каждая монета имеет одинаковую вероятность выпадения, то есть [LATEX]\frac{1}{10}[/LATEX], и все монеты независимы друг от друга. Как мы можем смоделировать такой эксперимент с помощью Python? Для этого я создал функцию [B]model_full_group[/B], которая принимает три аргумента: число событий [B]N[/B], массив вероятностей [B]p[/B] и число повторений [B]n[/B]. Эта функция проверяет, что сумма вероятностей равна 1, и затем проводит [B]n[/B] независимых испытаний для определения частоты каждого из [B]N[/B] возможных исходов. Функция возвращает результаты в виде долей, то есть отношения числа появлений каждого исхода к общему числу испытаний. Для моделирования жребия с 10 равновероятными исходами я задал параметры следующим образом: [CENTER][PYTHON]N_a = 10 #число событий p_a = np.ones(N_a) / N_a #равновероятные исходы n_a = 1000 #число повторений[/PYTHON][/CENTER] Затем я вызвал функцию [B]model_full_group[/B] с этими параметрами и сохранил результаты в переменной [B]results_a[/B]. [CENTER][PYTHON]results_a = model_full_group(N_a, p_a, n_a)[/PYTHON][/CENTER] [B][SIZE="4"]Полная группа случайных событий с заданными вероятностями[/SIZE][/B] Теперь давайте усложним задачу и представим, что у нас есть 5 разных монет, и каждая из них имеет свою вероятность выпадения. Например, первая монета выпадает с вероятностью 0.1, вторая - с вероятностью 0.2, и т.д. Как мы можем смоделировать такой эксперимент с помощью Python? Для этого мы можем использовать ту же функцию [B]model_full_group[/B], но задать другие параметры: [CENTER][PYTHON]N_b = 5 #число событий p_b = np.array([0.1, 0.2, 0.3, 0.25, 0.15]) #произвольные вероятности n_b = 500 #число повторений[/PYTHON][/CENTER] Затем я вызвал функцию [B]model_full_group[/B] с этими параметрами и сохранил результаты в переменной [B]results_b[/B]. [CENTER][PYTHON]results_b = model_full_group(N_b, p_b, n_b)[/PYTHON][/CENTER] [B][SIZE="4"]Анализ результатов[/SIZE][/B] Для анализа результатов каждого эксперимента я создал [B]DataFrame pandas[/B], который содержит следующие столбцы: № события, теоретическая вероятность и эмпирическая доля для каждого из двух экспериментов. [CENTER][ATTACH]8458[/ATTACH][/CENTER] Я также использовал библиотеку [B]openpyxl[/B] для создания файла [B]Excel[/B], который содержит все результаты экспериментов. Файл называется [B]Решение.xlsx[/B] и вы можете скачать его в конце блога. [CENTER][PYTHON]#датафрейм для вывода результатов df = pd.DataFrame({ "Событие": np.arange(1, max(N_a, N_b) + 1), "Вероятность (а)": np.append(p_a, np.zeros(max(N_a, N_b) - N_a)), "Доля (а)": np.append(results_a, np.zeros(max(N_a, N_b) - N_a)), "Вероятность (б)": np.append(p_b, np.zeros(max(N_a, N_b) - N_b)), "Доля (б)": np.append(results_b, np.zeros(max(N_a, N_b) - N_b)) }) #создаём новый файл excel wb = openpyxl.Workbook() #выбираем активный лист ws = wb.active #записываем заголовки таблицы headers = ["Событие", "Вероятность (а)", "Доля (а)", "Вероятность (б)", "Доля (б)"] for i in range(len(headers)): ws.cell(row=1, column=i+1).value = headers[i] #записываем данные из датафрейма for i in range(max(N_a, N_b)): ws.cell(row=i+2, column=1).value = df["Событие"][i] ws.cell(row=i+2, column=2).value = df["Вероятность (а)"][i] ws.cell(row=i+2, column=3).value = df["Доля (а)"][i] ws.cell(row=i+2, column=4).value = df["Вероятность (б)"][i] ws.cell(row=i+2, column=5).value = df["Доля (б)"][i] #сохраняем файл excel wb.save("Решение.xlsx") [/PYTHON][/CENTER] Но что же блог без визуализации? Я использовал [B]matplotlib[/B] для построения графиков, которые наглядно демонстрируют результаты каждого эксперимента. На этих графиках вы можете увидеть сравнение между теоретической вероятностью каждого исхода и его эмпирической долей. Вы можете заметить, что чем больше число повторений, тем ближе доли к вероятностям, что соответствует закону больших чисел. [CENTER][ATTACH]8459[/ATTACH] [PYTHON]#строим графики для сравнения вероятностей и долей fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 8)) ax1.bar(np.arange(1, N_a + 1), p_a, color="blue", label="Вероятность") ax1.bar(np.arange(1, N_a + 1), results_a, color="red", alpha=0.5, label="Доля") ax1.set_title("Моделирование жребия с N равновероятными исходами") ax1.set_xlabel("Событие") ax1.set_ylabel("Вероятность/Доля") ax1.legend(loc="lower center", bbox_to_anchor=(0.5, -0.2)) ax1.set_xticks(np.arange(1, N_a + 1)) ax1.set_xticklabels(np.arange(1, N_a + 1), rotation=0) ax2.bar(np.arange(1, N_b + 1), p_b, color="blue", label="Вероятность") ax2.bar(np.arange(1, N_b + 1), results_b, color="red", alpha=0.5, label="Доля") ax2.set_title("Моделирование полной группы N случайных событий с заданными вероятностями") ax2.set_xlabel("Событие") ax2.set_ylabel("Вероятность/Доля") ax2.legend(loc="lower center", bbox_to_anchor=(0.5, -0.2)) plt.show()[/PYTHON][/CENTER] Спасибо, что читаете мой блог. Я надеюсь, что он был полезен и интересен для вас. В этом блоге я показал, как можно использовать [B]Python[/B] для моделирования и анализа случайных событий. Я рассмотрел два типа моделирования: жребий с равновероятными исходами и полную группу случайных событий с заданными вероятностями. Также показал, как можно сохранять результаты экспериментов в файл [B]Excel[/B] и визуализировать их с помощью [B]matplotlib[/B]. Если вы хотите попробовать сами повторить мои эксперименты или изменить параметры, вы можете скопировать и вставить мой код в Google Colab. Также вы можете скачать файл [B]Excel[/B] с результатами экспериментов. [B][CENTER]Полный код:[/CENTER][/B] [CENTER][PYTHON]import numpy as np import pandas as pd import matplotlib.pyplot as plt import openpyxl #функция для моделирования полной группы N случайных событий def model_full_group(N, p, n): #проверяем, что сумма вероятностей равна 1 assert np.sum(p) == 1, "Сумма вероятностей должна быть равна 1" #создаём массив для хранения результатов испытаний results = np.zeros(N) #проводим n независимых испытаний for i in range(n): #генерируем случайное число от 0 до 1 r = np.random.rand() #определяем, какому событию соответствует это число for j in range(N): #если число меньше или равно сумме вероятностей до j-го события, то это событие произошло if r <= np.sum(p[:j+1]): #увеличиваем счетчик для этого события results[j] += 1 #прерываем цикл break #возвращаем результаты в виде долей return results / n #задаём параметры для пункта а) Моделирование жребия с N равновероятными исходами N_a = 10 #число событий p_a = np.ones(N_a) / N_a #равновероятные исходы n_a = 1000 #число повторений #вызываем функцию для пункта а) results_a = model_full_group(N_a, p_a, n_a) #задаём параметры для пункта б) Моделирование полной группы N случайных событий с заданными вероятностями N_b = 5 #число событий p_b = np.array([0.1, 0.2, 0.3, 0.25, 0.15]) #произвольные вероятности n_b = 500 #число повторений #вызываем функцию для пункта б) results_b = model_full_group(N_b, p_b, n_b) #датафрейм для вывода результатов df = pd.DataFrame({ "Событие": np.arange(1, max(N_a, N_b) + 1), "Вероятность (а)": np.append(p_a, np.zeros(max(N_a, N_b) - N_a)), "Доля (а)": np.append(results_a, np.zeros(max(N_a, N_b) - N_a)), "Вероятность (б)": np.append(p_b, np.zeros(max(N_a, N_b) - N_b)), "Доля (б)": np.append(results_b, np.zeros(max(N_a, N_b) - N_b)) }) #создаём новый файл excel wb = openpyxl.Workbook() #выбираем активный лист ws = wb.active #записываем заголовки таблицы headers = ["Событие", "Вероятность (а)", "Доля (а)", "Вероятность (б)", "Доля (б)"] for i in range(len(headers)): ws.cell(row=1, column=i+1).value = headers[i] #записываем данные из датафрейма for i in range(max(N_a, N_b)): ws.cell(row=i+2, column=1).value = df["Событие"][i] ws.cell(row=i+2, column=2).value = df["Вероятность (а)"][i] ws.cell(row=i+2, column=3).value = df["Доля (а)"][i] ws.cell(row=i+2, column=4).value = df["Вероятность (б)"][i] ws.cell(row=i+2, column=5).value = df["Доля (б)"][i] #сохраняем файл excel wb.save("Решение.xlsx") #выводим датафрейм в html-формате с css-стилями display(df.style.set_table_styles([ {"selector": "table", "props": [("font-family", '"Times New Roman"'), ("font-size", "14px")]}, {"selector": "th", "props": [("text-align", "center"), ("border", "1px solid black")]}, {"selector": "td", "props": [("text-align", "center"), ("border", "1px solid black")]}, {"selector": "tr:hover", "props": [("background-color", "none")]} ]).hide(axis="index")) print("") #строим графики для сравнения вероятностей и долей fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 8)) ax1.bar(np.arange(1, N_a + 1), p_a, color="blue", label="Вероятность") ax1.bar(np.arange(1, N_a + 1), results_a, color="red", alpha=0.5, label="Доля") ax1.set_title("Моделирование жребия с N равновероятными исходами") ax1.set_xlabel("Событие") ax1.set_ylabel("Вероятность/Доля") ax1.legend(loc="lower center", bbox_to_anchor=(0.5, -0.2)) ax1.set_xticks(np.arange(1, N_a + 1)) ax1.set_xticklabels(np.arange(1, N_a + 1), rotation=0) ax2.bar(np.arange(1, N_b + 1), p_b, color="blue", label="Вероятность") ax2.bar(np.arange(1, N_b + 1), results_b, color="red", alpha=0.5, label="Доля") ax2.set_title("Моделирование полной группы N случайных событий с заданными вероятностями") ax2.set_xlabel("Событие") ax2.set_ylabel("Вероятность/Доля") ax2.legend(loc="lower center", bbox_to_anchor=(0.5, -0.2)) plt.show()[/PYTHON][/CENTER] |
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.


