Сложные задачи по теории вероятностей с решением на Python

Введение

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

Задача 1: Монте-Карло для приближения числа π

Постановка задачи: Используя метод Монте-Карло, приближенно вычислить значение числа π.

Решение на Python:

import random
import matplotlib.pyplot as plt

# Параметры
num_points = 100000
inside_circle = 0

# Генерация точек и проверка попадания в четверть круга
for _ in range(num_points):
    x, y = random.random(), random.random()
    if x**2 + y**2 <= 1:
        inside_circle += 1

# Приближение числа π
pi_approx = (inside_circle / num_points) * 4
print(f"Приближение числа π: {pi_approx}")

Задача 2: Вероятность выпадения одинаковых дней рождения

Постановка задачи: Найти вероятность того, что в группе из n человек хотя бы у двух день рождения совпадет.

Решение на Python:

import math

def birthday_problem(n):
    probability = 1.0
    for i in range(n):
        probability *= (365 - i) / 365
    return 1 - probability

n = 23
print(f"Вероятность совпадения дней рождения для {n} человек: {birthday_problem(n):.4f}")

Задача 3: Закон больших чисел

Постановка задачи: Демонстрировать закон больших чисел, используя подбрасывание монеты.

Решение на Python:

import numpy as np

trials = 10000
results = np.random.binomial(1, 0.5, trials)
cumulative_mean = np.cumsum(results) / np.arange(1, trials + 1)

plt.plot(cumulative_mean)
plt.axhline(0.5, color='red', linestyle='dashed')
plt.xlabel('Количество испытаний')
plt.ylabel('Среднее значение')
plt.title('Закон больших чисел')
plt.show()

Задача 4: Байесовская вероятность

Постановка задачи: Рассчитать апостериорную вероятность заболевания при положительном результате теста.

Решение на Python:

def bayes_theorem(prior_A, prob_B_given_A, prob_B_given_not_A):
    prob_not_A = 1 - prior_A
    prob_B = prob_B_given_A * prior_A + prob_B_given_not_A * prob_not_A
    return (prob_B_given_A * prior_A) / prob_B

# Пример
prior_A = 0.01  # вероятность заболевания
prob_B_given_A = 0.99  # вероятность положительного теста при заболевании
prob_B_given_not_A = 0.05  # ложноположительные результаты

posterior = bayes_theorem(prior_A, prob_B_given_A, prob_B_given_not_A)
print(f"Апостериорная вероятность: {posterior:.4f}")

Задача 5: Марковские цепи

Постановка задачи: Смоделировать простую цепь Маркова с двумя состояниями.

Решение на Python:

states = ["A", "B"]
transition_matrix = [[0.9, 0.1], [0.5, 0.5]]

current_state = 0  # Начальное состояние A
sequence = []

for _ in range(100):
    sequence.append(states[current_state])
    current_state = np.random.choice([0, 1], p=transition_matrix[current_state])

print("Последовательность состояний:", sequence)

Задача 6: Случайные блуждания

Постановка задачи: Смоделировать одномерное случайное блуждание и рассчитать вероятность возвращения в начало.

Решение на Python:

steps = 1000
position = 0
trajectory = [position]

for _ in range(steps):
    step = np.random.choice([-1, 1])
    position += step
    trajectory.append(position)

plt.plot(trajectory)
plt.xlabel('Шаги')
plt.ylabel('Позиция')
plt.title('Случайное блуждание')
plt.show()

# Проверка возвращения в начало
returns_to_origin = trajectory.count(0)
print(f"Количество возвратов в начало: {returns_to_origin}")

Задача 7: Парадокс Монти Холла

Постановка задачи: Смоделировать парадокс Монти Холла и вычислить вероятность выигрыша при смене выбора.

Решение на Python:

def monty_hall_simulation(trials=10000):
    switch_wins = 0
    for _ in range(trials):
        doors = [0, 0, 1]  # 1 - приз, 0 - пусто
        np.random.shuffle(doors)
        choice = np.random.randint(0, 3)
        # Ведущий открывает дверь без приза
        for i in range(3):
            if i != choice and doors[i] == 0:
                open_door = i
                break
        # Игрок меняет выбор
        switch_choice = 3 - choice - open_door
        if doors[switch_choice] == 1:
            switch_wins += 1
    return switch_wins / trials

print(f"Вероятность выигрыша при смене двери: {monty_hall_simulation():.4f}")

Задача 8: Генерация случайных графов (Эрдёша-Реньи)

Постановка задачи: Сгенерировать случайный граф и проанализировать его свойства.

Решение на Python:

import networkx as nx

n = 100  # количество узлов
p = 0.05  # вероятность ребра

G = nx.erdos_renyi_graph(n, p)
nx.draw(G, node_size=20)
plt.title('Случайный граф Эрдёша-Реньи')
plt.show()

# Анализ
print(f"Количество узлов: {G.number_of_nodes()}")
print(f"Количество рёбер: {G.number_of_edges()}")

Задача 9: Сумма случайных величин

Постановка задачи: Исследовать распределение суммы двух равномерно распределенных случайных величин.

Решение на Python:

x = np.random.uniform(0, 1, 10000)
y = np.random.uniform(0, 1, 10000)
sum_xy = x + y

plt.hist(sum_xy, bins=50, density=True)
plt.title('Распределение суммы двух равномерных величин')
plt.show()

Задача 10: Параметрическая оценка (метод максимального правдоподобия)

Постановка задачи: Оценить параметр λ для распределения Пуассона с помощью метода максимального правдоподобия.

Решение на Python:

from scipy.stats import poisson

# Генерация данных
lambda_true = 3
sample = np.random.poisson(lambda_true, 1000)

# Оценка параметра
lambda_estimate = np.mean(sample)

print(f"Истинное λ: {lambda_true}, Оценённое λ: {lambda_estimate:.4f}")

Задача 11: Метод бутстрэппинга

Постановка задачи: Оценить дисперсию среднего с использованием бутстрэппинга.

Решение на Python:

bootstrap_samples = 1000
sample_data = np.random.normal(0, 1, 100)
means = []

for _ in range(bootstrap_samples):
    resample = np.random.choice(sample_data, size=len(sample_data), replace=True)
    means.append(np.mean(resample))

plt.hist(means, bins=30, density=True)
plt.title('Оценка распределения среднего (бутстрэппинг)')
plt.show()

print(f"Оценка дисперсии: {np.var(means):.4f}")

Задача 12: Парадокс Симпсона

Постановка задачи: Продемонстрировать парадокс Симпсона на примере агрегированных данных.

Решение на Python:

import networkx as nx

n = 100 # количество узлов
p = 0.05 # вероятность ребра

G = nx.erdos_renyi_graph(n, p)
nx.draw(G, node_size=20)
plt.title('Случайный граф Эрдёша-Реньи')
plt.show()

# Анализ
print(f"Количество узлов: {G.number_of_nodes()}")
print(f"Количество рёбер: {G.number_of_edges()}")

Заключение

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

+1
0
+1
5
+1
0
+1
0
+1
3

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *