f
This commit is contained in:
		
							parent
							
								
									9cef66de67
								
							
						
					
					
						commit
						abe79f18a9
					
				
							
								
								
									
										178
									
								
								app/menu_load.py
									
									
									
									
									
								
							
							
						
						
									
										178
									
								
								app/menu_load.py
									
									
									
									
									
								
							@ -1,178 +0,0 @@
 | 
			
		||||
from app.utils.system import clear_console
 | 
			
		||||
from app.zadachi.zadacha1 import zadacha1
 | 
			
		||||
from app.zadachi.zadacha2 import zadacha2
 | 
			
		||||
from app.zadachi.zadacha3 import zadacha3
 | 
			
		||||
from app.zadachi.zadacha4 import zadacha4
 | 
			
		||||
from app.zadachi.zadacha5 import zadacha5
 | 
			
		||||
 | 
			
		||||
class menu:
 | 
			
		||||
    
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        pass  # Конструктор пока пустой, при необходимости можно добавить параметры
 | 
			
		||||
 | 
			
		||||
    def main_menu(self):
 | 
			
		||||
        clear_console()
 | 
			
		||||
        while True:
 | 
			
		||||
            print('\nMain Menu:')
 | 
			
		||||
            print('1. Задача 1')
 | 
			
		||||
            print('2. Задача 2')
 | 
			
		||||
            print('3. Задача 3')
 | 
			
		||||
            print('4. Задача 4')
 | 
			
		||||
            print('5. Задача 5')
 | 
			
		||||
            print('0. Exit')
 | 
			
		||||
 | 
			
		||||
            choice = input('Select an option: ')
 | 
			
		||||
 | 
			
		||||
            clear_console()
 | 
			
		||||
            if choice == '1':
 | 
			
		||||
                self.zadacha1_menu()  # Переход к подменю Задачи 1
 | 
			
		||||
            elif choice == '2':
 | 
			
		||||
                self.zadacha2_menu()  # Переход к подменю Задачи 2
 | 
			
		||||
            elif choice == '3':
 | 
			
		||||
                self.zadacha3_menu()  # Переход к подменю Задачи 3
 | 
			
		||||
            elif choice == '4':
 | 
			
		||||
                self.zadacha4_menu()  # Добавлен вызов меню задачи 4
 | 
			
		||||
            elif choice == '5':
 | 
			
		||||
                self.zadacha5_menu()  # Добавлен вызов меню задачи 5
 | 
			
		||||
            elif choice == '0':
 | 
			
		||||
                print('Exiting program...')
 | 
			
		||||
                break
 | 
			
		||||
            else:
 | 
			
		||||
                print('Invalid option')
 | 
			
		||||
 | 
			
		||||
    def zadacha1_menu(self):
 | 
			
		||||
        """Меню для задачи 1 с подкатегориями."""
 | 
			
		||||
        clear_console()
 | 
			
		||||
        while True:
 | 
			
		||||
            print('\nЗадача 1:')
 | 
			
		||||
            print('1. Линейно сгенерировать массив Y, зависящий от x')
 | 
			
		||||
            print('2. Квадратично сгенерировать массив Y, зависящий от x')
 | 
			
		||||
            print('0. Назад')
 | 
			
		||||
 | 
			
		||||
            choice = input('Выберите подкатегорию: ')
 | 
			
		||||
 | 
			
		||||
            clear_console()
 | 
			
		||||
            z1 = zadacha1()  # создаем объект для задачи 1
 | 
			
		||||
 | 
			
		||||
            if choice == '1':
 | 
			
		||||
                z1.plot_lin_data()  # Выполнить первую подзадачу
 | 
			
		||||
                #return  # Вернуться в основное меню после выполнения
 | 
			
		||||
            elif choice == '2':
 | 
			
		||||
                z1.plot_sqr_data()  # Выполнить вторую подзадачу
 | 
			
		||||
                #return  # Вернуться в основное меню после выполнения
 | 
			
		||||
            elif choice == '0':
 | 
			
		||||
                break  # Вернуться в основное меню
 | 
			
		||||
            else:
 | 
			
		||||
                print('Неверный выбор, попробуйте снова.')
 | 
			
		||||
 | 
			
		||||
    def zadacha2_menu(self):
 | 
			
		||||
        """Меню для задачи 2 (расчет коэффициентов методом наименьших квадратов)."""
 | 
			
		||||
        clear_console()
 | 
			
		||||
        z1 = zadacha1()  # Используем объект задачи 1 для генерации данных
 | 
			
		||||
        z2 = zadacha2()  # Создаем объект для задачи 2
 | 
			
		||||
        
 | 
			
		||||
        while True:
 | 
			
		||||
            print('\nЗадача 2:')
 | 
			
		||||
            print('1. Рассчитать коэффициенты b0 и b1 для линейной модели')
 | 
			
		||||
            print('2. Сделать прогноз по рассчитанным коэффициентам')
 | 
			
		||||
            print('0. Назад')
 | 
			
		||||
 | 
			
		||||
            choice = input('Выберите подкатегорию: ')
 | 
			
		||||
 | 
			
		||||
            clear_console()
 | 
			
		||||
 | 
			
		||||
            if choice == '1':
 | 
			
		||||
                # Генерация линейных данных с помощью функции из задачи 1
 | 
			
		||||
                x_data, y_data = z1.create_lin_array()
 | 
			
		||||
 | 
			
		||||
                # Рассчет коэффициентов b0 и b1 методом наименьших квадратов
 | 
			
		||||
                b0, b1 = z2.calculate_coefficients(x_data, y_data)
 | 
			
		||||
 | 
			
		||||
                print(f'Рассчитанные коэффициенты:')
 | 
			
		||||
                print(f'b0 (свободный член) = {b0}')
 | 
			
		||||
                print(f'b1 (коэффициент наклона) = {b1}')
 | 
			
		||||
            elif choice == '2':
 | 
			
		||||
                # Пример предсказания на новых данных
 | 
			
		||||
                x_data, y_data = z1.create_lin_array()  # Сначала генерируем данные
 | 
			
		||||
                b0, b1 = z2.calculate_coefficients(x_data, y_data)  # Рассчитываем коэффициенты
 | 
			
		||||
 | 
			
		||||
                # Выполняем прогноз
 | 
			
		||||
                predicted_y = z2.predict(x_data, b0, b1)
 | 
			
		||||
 | 
			
		||||
                print(f'Предсказанные значения Y на основе рассчитанных коэффициентов:')
 | 
			
		||||
                print(predicted_y)
 | 
			
		||||
            elif choice == '0':
 | 
			
		||||
                break  # Вернуться в основное меню
 | 
			
		||||
            else:
 | 
			
		||||
                print('Неверный выбор, попробуйте снова.')
 | 
			
		||||
 | 
			
		||||
    def zadacha3_menu(self):
 | 
			
		||||
        """Меню для задачи 3 (построение графика регрессии и расчет метрик)."""
 | 
			
		||||
        clear_console()
 | 
			
		||||
        z1 = zadacha1()  # Используем объект задачи 1 для генерации данных
 | 
			
		||||
        z2 = zadacha2()  # Используем объект задачи 2 для расчета коэффициентов
 | 
			
		||||
        
 | 
			
		||||
        while True:
 | 
			
		||||
            print('\nЗадача 3:')
 | 
			
		||||
            print('1. Построить график регрессии и рассчитать метрики')
 | 
			
		||||
            print('0. Назад')
 | 
			
		||||
 | 
			
		||||
            choice = input('Выберите подкатегорию: ')
 | 
			
		||||
 | 
			
		||||
            clear_console()
 | 
			
		||||
 | 
			
		||||
            if choice == '1':
 | 
			
		||||
                x_data, y_data = z1.create_lin_array()
 | 
			
		||||
                b0, b1 = z2.calculate_coefficients(x_data, y_data)
 | 
			
		||||
 | 
			
		||||
                # Создаем объект задачи 3 и выполняем построение графика
 | 
			
		||||
                z3 = zadacha3(x_data, y_data, b0, b1)
 | 
			
		||||
                z3.plot_regression()
 | 
			
		||||
            elif choice == '0':
 | 
			
		||||
                break  # Вернуться в основное меню
 | 
			
		||||
            else:
 | 
			
		||||
                print('Неверный выбор, попробуйте снова.')
 | 
			
		||||
 | 
			
		||||
    def zadacha4_menu(self):
 | 
			
		||||
        """Меню для задачи 4"""
 | 
			
		||||
        clear_console()
 | 
			
		||||
        #z4 = zadacha4()  # Создаем объект задачи 4
 | 
			
		||||
        
 | 
			
		||||
        while True:
 | 
			
		||||
            print('\nЗадача 4:')
 | 
			
		||||
            print('1. Провести визуальный анализ остатков')
 | 
			
		||||
            print('0. Назад')
 | 
			
		||||
 | 
			
		||||
            choice = input('Выберите подкатегорию: ')
 | 
			
		||||
 | 
			
		||||
            clear_console()
 | 
			
		||||
 | 
			
		||||
            if choice == '1':
 | 
			
		||||
                z4 = zadacha4()
 | 
			
		||||
                z4.analyze_residuals()
 | 
			
		||||
            elif choice == '0':
 | 
			
		||||
                break
 | 
			
		||||
            else:
 | 
			
		||||
                print('Неверный выбор, попробуйте снова.')
 | 
			
		||||
 | 
			
		||||
    def zadacha5_menu(self):
 | 
			
		||||
        """Меню для задачи 5"""
 | 
			
		||||
        clear_console()
 | 
			
		||||
        
 | 
			
		||||
        while True:
 | 
			
		||||
            print('\nЗадача 5:')
 | 
			
		||||
            print('1. Рассчитать статистики для определения выполнения условий применения линейной регрессии')
 | 
			
		||||
            print('0. Назад')
 | 
			
		||||
 | 
			
		||||
            choice = input('Выберите подкатегорию: ')
 | 
			
		||||
 | 
			
		||||
            clear_console()
 | 
			
		||||
 | 
			
		||||
            if choice == '1':
 | 
			
		||||
                z5 = zadacha5()
 | 
			
		||||
                z5.calculate_spearman_rank_test()
 | 
			
		||||
                z5.calculate_gq_test()
 | 
			
		||||
            elif choice == '0':
 | 
			
		||||
                break
 | 
			
		||||
            else:
 | 
			
		||||
                print('Неверный выбор, попробуйте снова.')
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
debug=0
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
import os
 | 
			
		||||
import platform
 | 
			
		||||
 | 
			
		||||
def clear_console():
 | 
			
		||||
    """Очистить консоль в зависимости от операционной системы."""
 | 
			
		||||
    os_name = platform.system()
 | 
			
		||||
    if os_name == 'Windows':
 | 
			
		||||
        os.system('cls')
 | 
			
		||||
    else:
 | 
			
		||||
        os.system('clear')
 | 
			
		||||
@ -1,60 +0,0 @@
 | 
			
		||||
import numpy as np
 | 
			
		||||
import matplotlib.pyplot as plt
 | 
			
		||||
 | 
			
		||||
class zadacha1:
 | 
			
		||||
    
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        pass  # Конструктор пока пустой, при необходимости можно добавить параметры
 | 
			
		||||
    
 | 
			
		||||
    # Метод для генерации линейного массива данных
 | 
			
		||||
    def create_lin_array(self, b0=2, b1=4, N=500, noise_std=10):
 | 
			
		||||
        """
 | 
			
		||||
        Генерация массива данных по линейной зависимости Y = b0 + b1 * X + error
 | 
			
		||||
        :param b0: свободный коэффициент
 | 
			
		||||
        :param b1: коэффициент при X
 | 
			
		||||
        :param N: количество точек данных
 | 
			
		||||
        :param noise_std: стандартное отклонение для случайной ошибки
 | 
			
		||||
        :return: массивы X и Y
 | 
			
		||||
        """
 | 
			
		||||
        X = np.linspace(1, 500, N)  # создаем массив X с равномерным шагом
 | 
			
		||||
        error = np.random.normal(0, noise_std, N)  # генерируем шум
 | 
			
		||||
        Y = b0 + b1 * X + error  # генерируем Y по линейному закону
 | 
			
		||||
        return X, Y
 | 
			
		||||
 | 
			
		||||
    # Метод для генерации квадратичного массива данных
 | 
			
		||||
    def create_sqr_array(self, a=1, b=3, c=2, N=500, noise_std=10):
 | 
			
		||||
        """
 | 
			
		||||
        Генерация массива данных по квадратичной зависимости Y = a * X^2 + b * X + c + error
 | 
			
		||||
        :param a: коэффициент при X^2
 | 
			
		||||
        :param b: коэффициент при X
 | 
			
		||||
        :param c: свободный коэффициент
 | 
			
		||||
        :param N: количество точек данных
 | 
			
		||||
        :param noise_std: стандартное отклонение для случайной ошибки
 | 
			
		||||
        :return: массивы X и Y
 | 
			
		||||
        """
 | 
			
		||||
        X = np.linspace(1, 500, N)  # создаем массив X
 | 
			
		||||
        error = np.random.normal(0, noise_std, N)  # генерируем шум
 | 
			
		||||
        Y = a * X**2 + b * X + c + error  # генерируем Y по квадратичному закону
 | 
			
		||||
        return X, Y
 | 
			
		||||
 | 
			
		||||
    # Метод для отображения графика линейных данных
 | 
			
		||||
    def plot_lin_data(self, b0=2, b1=4, N=500, noise_std=10):
 | 
			
		||||
        """
 | 
			
		||||
        Отображение сгенерированных линейных данных и теоретической линии
 | 
			
		||||
        """
 | 
			
		||||
        X, Y = self.create_lin_array(b0, b1, N, noise_std)  # Генерация данных
 | 
			
		||||
        plt.scatter(X, Y)  # График рассеяния
 | 
			
		||||
        plt.plot(X, b0 + b1 * X, color='red')  # Линейная функция без шума
 | 
			
		||||
        plt.title("Линейная зависимость с шумом")
 | 
			
		||||
        plt.show()
 | 
			
		||||
 | 
			
		||||
    # Метод для отображения графика квадратичных данных
 | 
			
		||||
    def plot_sqr_data(self, a=1, b=3, c=2, N=500, noise_std=10):
 | 
			
		||||
        """
 | 
			
		||||
        Отображение сгенерированных квадратичных данных и теоретической кривой
 | 
			
		||||
        """
 | 
			
		||||
        X, Y = self.create_sqr_array(a, b, c, N, noise_std)  # Генерация данных
 | 
			
		||||
        plt.scatter(X, Y)  # График рассеяния
 | 
			
		||||
        plt.plot(X, a * X**2 + b * X + c, color='red')  # Квадратичная функция без шума
 | 
			
		||||
        plt.title("Квадратичная зависимость с шумом")
 | 
			
		||||
        plt.show()
 | 
			
		||||
@ -1,35 +0,0 @@
 | 
			
		||||
import numpy as np
 | 
			
		||||
 | 
			
		||||
class zadacha2:
 | 
			
		||||
    def calculate_coefficients(self, X, Y):
 | 
			
		||||
        """
 | 
			
		||||
        Функция для расчета коэффициентов b0 и b1 по методу наименьших квадратов (МНК)
 | 
			
		||||
        :param X: массив значений независимой переменной
 | 
			
		||||
        :param Y: массив значений зависимой переменной
 | 
			
		||||
        :return: коэффициенты b0 и b1
 | 
			
		||||
        """
 | 
			
		||||
        n = len(X)
 | 
			
		||||
        
 | 
			
		||||
        # Вычисляем средние значения X и Y
 | 
			
		||||
        mean_x = np.mean(X)
 | 
			
		||||
        mean_y = np.mean(Y)
 | 
			
		||||
        
 | 
			
		||||
        # Вычисляем коэффициент b1
 | 
			
		||||
        numerator = np.sum((X - mean_x) * (Y - mean_y))
 | 
			
		||||
        denominator = np.sum((X - mean_x) ** 2)
 | 
			
		||||
        b1 = numerator / denominator
 | 
			
		||||
        
 | 
			
		||||
        # Вычисляем коэффициент b0
 | 
			
		||||
        b0 = mean_y - b1 * mean_x
 | 
			
		||||
        
 | 
			
		||||
        return b0, b1
 | 
			
		||||
 | 
			
		||||
    def predict(self, X, b0, b1):
 | 
			
		||||
        """
 | 
			
		||||
        Функция для предсказания значений Y на основе коэффициентов b0 и b1
 | 
			
		||||
        :param X: массив значений независимой переменной
 | 
			
		||||
        :param b0: коэффициент b0 (свободный член)
 | 
			
		||||
        :param b1: коэффициент b1 (коэффициент при X)
 | 
			
		||||
        :return: предсказанные значения Y
 | 
			
		||||
        """
 | 
			
		||||
        return b0 + b1 * X
 | 
			
		||||
@ -1,54 +0,0 @@
 | 
			
		||||
import numpy as np
 | 
			
		||||
import matplotlib.pyplot as plt
 | 
			
		||||
 | 
			
		||||
class zadacha3:
 | 
			
		||||
    def __init__(self, X, Y, b0, b1):
 | 
			
		||||
        self.X = X
 | 
			
		||||
        self.Y = Y
 | 
			
		||||
        self.b0 = b0
 | 
			
		||||
        self.b1 = b1
 | 
			
		||||
        
 | 
			
		||||
    def calculate_sse(self):
 | 
			
		||||
        """
 | 
			
		||||
        Функция для расчета суммы квадратов ошибок (SSE)
 | 
			
		||||
        :return: SSE
 | 
			
		||||
        """
 | 
			
		||||
        Y_pred = self.b0 + self.b1 * self.X
 | 
			
		||||
        sse = np.sum((self.Y - Y_pred) ** 2)
 | 
			
		||||
        return sse
 | 
			
		||||
 | 
			
		||||
    def calculate_r_squared(self):
 | 
			
		||||
        """
 | 
			
		||||
        Функция для расчета коэффициента детерминации R^2
 | 
			
		||||
        :return: R^2
 | 
			
		||||
        """
 | 
			
		||||
        y_mean = np.mean(self.Y)
 | 
			
		||||
        ss_total = np.sum((self.Y - y_mean) ** 2)
 | 
			
		||||
        ss_residual = self.calculate_sse()
 | 
			
		||||
        r_squared = 1 - (ss_residual / ss_total)
 | 
			
		||||
        return r_squared
 | 
			
		||||
 | 
			
		||||
    def plot_regression(self):
 | 
			
		||||
        """
 | 
			
		||||
        Функция для построения графика регрессии и отображения метрик SSE и R^2
 | 
			
		||||
        """
 | 
			
		||||
        Y_pred = self.b0 + self.b1 * self.X
 | 
			
		||||
        
 | 
			
		||||
        plt.figure(figsize=(10, 6))
 | 
			
		||||
        
 | 
			
		||||
        # График рассеяния и регрессионная прямая
 | 
			
		||||
        plt.subplot(2, 1, 1)
 | 
			
		||||
        plt.scatter(self.X, self.Y, label='Данные')
 | 
			
		||||
        plt.plot(self.X, Y_pred, color='red', label='Регрессия')
 | 
			
		||||
        plt.title("Линейная регрессия")
 | 
			
		||||
        plt.xlabel("X")
 | 
			
		||||
        plt.ylabel("Y")
 | 
			
		||||
        plt.legend()
 | 
			
		||||
 | 
			
		||||
        # Расчет метрик и отображение на графике
 | 
			
		||||
        sse = self.calculate_sse()
 | 
			
		||||
        r_squared = self.calculate_r_squared()
 | 
			
		||||
        plt.text(0.05, 0.95, f"SSE: {sse:.2f}\nR^2: {r_squared:.2f}",
 | 
			
		||||
                 transform=plt.gca().transAxes, verticalalignment='top')
 | 
			
		||||
        
 | 
			
		||||
        plt.show()
 | 
			
		||||
@ -1,62 +0,0 @@
 | 
			
		||||
import numpy as np
 | 
			
		||||
import matplotlib.pyplot as plt
 | 
			
		||||
from app.zadachi.zadacha2 import zadacha2
 | 
			
		||||
from app.zadachi.zadacha1 import zadacha1
 | 
			
		||||
 | 
			
		||||
class zadacha4:
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.z1 = zadacha1()
 | 
			
		||||
        self.z2 = zadacha2()
 | 
			
		||||
 | 
			
		||||
    def analyze_residuals(self):
 | 
			
		||||
        """
 | 
			
		||||
        Выполняет визуальный анализ остатков по линейной модели.
 | 
			
		||||
        Строит графики 2*2: скаттерограмма, график исходной зависимости, 
 | 
			
		||||
        распределение остатков и гистограмму остатков.
 | 
			
		||||
        """
 | 
			
		||||
        # Генерируем данные
 | 
			
		||||
        X, Y = self.z1.create_lin_array()
 | 
			
		||||
        
 | 
			
		||||
        # Рассчитываем коэффициенты методом наименьших квадратов
 | 
			
		||||
        b0, b1 = self.z2.calculate_coefficients(X, Y)
 | 
			
		||||
        
 | 
			
		||||
        # Предсказанные значения
 | 
			
		||||
        Y_pred = self.z2.predict(X, b0, b1)
 | 
			
		||||
        
 | 
			
		||||
        # Вычисляем остатки
 | 
			
		||||
        residuals = Y - Y_pred
 | 
			
		||||
        
 | 
			
		||||
        # Создаем графики 2*2
 | 
			
		||||
        fig, axs = plt.subplots(2, 2, figsize=(12, 8))
 | 
			
		||||
        
 | 
			
		||||
        # Первый график: скаттерограмма с линией МНК
 | 
			
		||||
        axs[0, 0].scatter(X, Y, label='Данные с шумом', alpha=0.6)
 | 
			
		||||
        axs[0, 0].plot(X, Y_pred, color='red', label='Прямая по МНК')
 | 
			
		||||
        axs[0, 0].set_title('Скаттерограмма и прямая по МНК')
 | 
			
		||||
        axs[0, 0].legend()
 | 
			
		||||
        
 | 
			
		||||
        # Второй график: исходная зависимость и линия МНК
 | 
			
		||||
        axs[0, 1].scatter(X, Y, label='Данные', alpha=0.6)
 | 
			
		||||
        axs[0, 1].plot(X, self.z1.create_lin_array(b0, b1, len(X))[1], color='green', label='Истинная линия')
 | 
			
		||||
        axs[0, 1].plot(X, Y_pred, color='red', linestyle='--', label='Прямая по МНК')
 | 
			
		||||
        axs[0, 1].set_title('Истинная линия и прямая по МНК')
 | 
			
		||||
        axs[0, 1].legend()
 | 
			
		||||
        
 | 
			
		||||
        # Третий график: распределение остатков
 | 
			
		||||
        axs[1, 0].scatter(X, residuals, color='purple', alpha=0.6)
 | 
			
		||||
        axs[1, 0].axhline(y=0, color='red', linestyle='--')
 | 
			
		||||
        axs[1, 0].set_title('Распределение остатков')
 | 
			
		||||
        
 | 
			
		||||
        # Четвертый график: гистограмма остатков
 | 
			
		||||
        axs[1, 1].hist(residuals, bins=30, color='orange', edgecolor='black', alpha=0.7)
 | 
			
		||||
        axs[1, 1].set_title('Гистограмма остатков')
 | 
			
		||||
        
 | 
			
		||||
        # Выравниваем графики и отображаем
 | 
			
		||||
        plt.tight_layout()
 | 
			
		||||
        plt.show()
 | 
			
		||||
        
 | 
			
		||||
        # Отдельное окно для гистограммы
 | 
			
		||||
        plt.figure()
 | 
			
		||||
        plt.hist(residuals, bins=30, color='orange', edgecolor='black', alpha=0.7)
 | 
			
		||||
        plt.title('Гистограмма остатков (отдельно)')
 | 
			
		||||
        plt.show()
 | 
			
		||||
@ -1,79 +0,0 @@
 | 
			
		||||
import numpy as np
 | 
			
		||||
from app.zadachi.zadacha2 import zadacha2
 | 
			
		||||
from app.zadachi.zadacha1 import zadacha1
 | 
			
		||||
 | 
			
		||||
class zadacha5:
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.z1 = zadacha1()
 | 
			
		||||
        self.z2 = zadacha2()
 | 
			
		||||
 | 
			
		||||
    def calculate_spearman_rank_test(self):
 | 
			
		||||
        """
 | 
			
		||||
        Выполняет тест ранговой корреляции Спирмена для проверки взаимосвязи между X и Y.
 | 
			
		||||
        :return: коэффициент корреляции Спирмена и p-value
 | 
			
		||||
        """
 | 
			
		||||
        # Генерируем данные
 | 
			
		||||
        X, Y = self.z1.create_lin_array()
 | 
			
		||||
        
 | 
			
		||||
        # Вычисляем ранги
 | 
			
		||||
        X_ranks = np.argsort(np.argsort(X))
 | 
			
		||||
        Y_ranks = np.argsort(np.argsort(Y))
 | 
			
		||||
        
 | 
			
		||||
        # Вычисляем разницу рангов
 | 
			
		||||
        diff_ranks = X_ranks - Y_ranks
 | 
			
		||||
        
 | 
			
		||||
        # Числитель формулы Спирмена
 | 
			
		||||
        numerator = 6 * np.sum(diff_ranks**2)
 | 
			
		||||
        
 | 
			
		||||
        # Количество наблюдений
 | 
			
		||||
        n = len(X)
 | 
			
		||||
        
 | 
			
		||||
        # Коэффициент корреляции Спирмена
 | 
			
		||||
        spearman_coef = 1 - numerator / (n * (n**2 - 1))
 | 
			
		||||
        
 | 
			
		||||
        # Оценка значимости результата (p-value) не рассчитывается вручную здесь, но коэффициент корреляции интерпретируется.
 | 
			
		||||
        print(f'Коэффициент корреляции Спирмена: {spearman_coef:.3f}')
 | 
			
		||||
        
 | 
			
		||||
        # Интерпретация результата
 | 
			
		||||
        if np.abs(spearman_coef) > 0.5:
 | 
			
		||||
            print("Существует значимая взаимосвязь между X и Y.")
 | 
			
		||||
        else:
 | 
			
		||||
            print("Взаимосвязь между X и Y слабая или отсутствует.")
 | 
			
		||||
 | 
			
		||||
    def calculate_gq_test(self):
 | 
			
		||||
        """
 | 
			
		||||
        Выполняет тест Голдфелда-Квандта для проверки гомоскедастичности.
 | 
			
		||||
        :return: значение статистики F и результат теста
 | 
			
		||||
        """
 | 
			
		||||
        # Генерируем данные
 | 
			
		||||
        X, Y = self.z1.create_lin_array()
 | 
			
		||||
        
 | 
			
		||||
        # Рассчитываем коэффициенты регрессии
 | 
			
		||||
        b0, b1 = self.z2.calculate_coefficients(X, Y)
 | 
			
		||||
        
 | 
			
		||||
        # Вычисляем остатки
 | 
			
		||||
        residuals = Y - self.z2.predict(X, b0, b1)
 | 
			
		||||
        
 | 
			
		||||
        # Сортируем данные по X для выполнения теста
 | 
			
		||||
        sorted_indices = np.argsort(X)
 | 
			
		||||
        residuals_sorted = residuals[sorted_indices]
 | 
			
		||||
        
 | 
			
		||||
        # Разбиваем данные на две части
 | 
			
		||||
        split_index = len(residuals_sorted) // 2
 | 
			
		||||
        residuals_low = residuals_sorted[:split_index]
 | 
			
		||||
        residuals_high = residuals_sorted[split_index:]
 | 
			
		||||
        
 | 
			
		||||
        # Вычисляем средние квадраты остатков
 | 
			
		||||
        var_low = np.var(residuals_low, ddof=1)
 | 
			
		||||
        var_high = np.var(residuals_high, ddof=1)
 | 
			
		||||
        
 | 
			
		||||
        # Тестовая статистика F
 | 
			
		||||
        f_stat = var_high / var_low
 | 
			
		||||
        
 | 
			
		||||
        print(f'Статистика F: {f_stat:.3f}')
 | 
			
		||||
        
 | 
			
		||||
        # Интерпретация результата
 | 
			
		||||
        if f_stat > 2 or f_stat < 0.5:
 | 
			
		||||
            print("Остатки не гомоскедастичны. Условие линейной регрессии нарушено.")
 | 
			
		||||
        else:
 | 
			
		||||
            print("Остатки гомоскедастичны. Условие линейной регрессии выполнено.")
 | 
			
		||||
							
								
								
									
										151
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										151
									
								
								main.py
									
									
									
									
									
								
							@ -1,11 +1,142 @@
 | 
			
		||||
from app.utils.config import debug
 | 
			
		||||
from app.menu_load import menu
 | 
			
		||||
import matplotlib.pyplot as plt
 | 
			
		||||
import matplotlib
 | 
			
		||||
import numpy as np
 | 
			
		||||
matplotlib.use('TkAgg')
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    if debug == True:
 | 
			
		||||
        print("Running in debug mode...")
 | 
			
		||||
        from test_module.debug_main import debug_main_start
 | 
			
		||||
        debug_main_start()
 | 
			
		||||
    else:
 | 
			
		||||
        mn = menu()
 | 
			
		||||
        mn.main_menu()
 | 
			
		||||
# 1. Функция для генерации линейной зависимости
 | 
			
		||||
def F(b0, b1, N):
 | 
			
		||||
    # Генерация случайных данных для X
 | 
			
		||||
    x = np.random.uniform(0, 10, size=N)
 | 
			
		||||
    x.sort()  # Упорядочиваем массив для наглядности
 | 
			
		||||
    err = np.random.normal(0, 2, N)  # Добавляем случайный шум
 | 
			
		||||
    Y = b0 + b1 * x + err  # Вычисляем Y с линейной зависимостью и шумом
 | 
			
		||||
    # Построение графика рассеяния и идеальной линейной функции
 | 
			
		||||
    plt.scatter(x, Y, facecolors='none', edgecolor='blue', s=40)
 | 
			
		||||
    plt.plot(x, b0 + b1 * x, color='red')
 | 
			
		||||
    plt.title("Линейная зависимость с шумом")
 | 
			
		||||
    plt.xlabel('X')
 | 
			
		||||
    plt.ylabel('Data Y')
 | 
			
		||||
    plt.show()
 | 
			
		||||
    return Y, x  # Возвращаем массивы X и Y
 | 
			
		||||
 | 
			
		||||
# 2. Функция для генерации квадратичной зависимости
 | 
			
		||||
def F2(a, b, c, N):
 | 
			
		||||
    xp = np.random.uniform(0, 10, size=N)
 | 
			
		||||
    xp.sort()
 | 
			
		||||
    err = np.random.normal(0, 5, N)  # Шум для квадратичной зависимости
 | 
			
		||||
    Yp = a * xp ** 2 + b * xp + c + err
 | 
			
		||||
    # Построение графика рассеяния и идеальной квадратичной функции
 | 
			
		||||
    plt.scatter(xp, Yp, facecolors='none', edgecolor='blue', s=40)
 | 
			
		||||
    plt.plot(xp, a * xp ** 2 + b * xp + c, color='red')
 | 
			
		||||
    plt.title("Квадратичная зависимость с шумом")
 | 
			
		||||
    plt.xlabel('X')
 | 
			
		||||
    plt.ylabel('Data Yp')
 | 
			
		||||
    plt.show()
 | 
			
		||||
    return Yp, xp
 | 
			
		||||
 | 
			
		||||
# Генерация данных
 | 
			
		||||
Y, x = F(6, 9, 500)  # Линейная зависимость
 | 
			
		||||
Yp, xp = F2(3, 1, -2, 500)  # Квадратичная зависимость
 | 
			
		||||
 | 
			
		||||
# 3. Метод наименьших квадратов (МНК) для расчета коэффициентов линейной регрессии
 | 
			
		||||
def MHk(Y, x):
 | 
			
		||||
    # Вычисление коэффициента наклона (b1)
 | 
			
		||||
    b1 = sum((x - np.mean(x)) * (Y - np.mean(Y))) / sum((x - np.mean(x)) ** 2)
 | 
			
		||||
    # Вычисление свободного члена (b0)
 | 
			
		||||
    b0 = np.mean(Y) - b1 * np.mean(x)
 | 
			
		||||
    return b1, b0
 | 
			
		||||
 | 
			
		||||
b1, b0 = MHk(Y, x)  # Коэффициенты для линейной зависимости
 | 
			
		||||
print(f"Линейные коэффициенты: b1={b1:.2f}, b0={b0:.2f}")
 | 
			
		||||
 | 
			
		||||
# Аналогичная функция для квадратичных данных
 | 
			
		||||
def MHkp(Yp, xp):
 | 
			
		||||
    b1p = sum((xp - np.mean(xp)) * (Yp - np.mean(Yp))) / sum((xp - np.mean(xp)) ** 2)
 | 
			
		||||
    b0p = np.mean(Yp) - b1p * np.mean(xp)
 | 
			
		||||
    return b1p, b0p
 | 
			
		||||
 | 
			
		||||
b1p, b0p = MHkp(Yp, xp)
 | 
			
		||||
print(f"Коэффициенты квадратичной регрессии: b1={b1p:.2f}, b0={b0p:.2f}")
 | 
			
		||||
 | 
			
		||||
# 4. Построение регрессионных линий
 | 
			
		||||
Y_l = b0 + b1 * x  # Линейная регрессия
 | 
			
		||||
Y_s = b0p + b1p * xp  # Квадратичная регрессия
 | 
			
		||||
 | 
			
		||||
# 5. Вычисление SSE и коэффициента детерминации (R²)
 | 
			
		||||
SSE = sum((Y - (b0 + b1 * x)) ** 2)  # Ошибка для линейной регрессии
 | 
			
		||||
SST = sum((Y - np.mean(Y)) ** 2)  # Общая дисперсия данных
 | 
			
		||||
R2_lin = 1 - (SSE / SST)  # Коэффициент детерминации для линейной
 | 
			
		||||
print(f"SSE линейной: {SSE:.2f}, R^2 линейной функции: {R2_lin:.3f}")
 | 
			
		||||
 | 
			
		||||
SSEp = sum((Yp - Y_s) ** 2)  # Ошибка для квадратичной регрессии
 | 
			
		||||
SSTp = sum((Yp - np.mean(Yp)) ** 2)
 | 
			
		||||
R2_quad = 1 - (SSEp / SSTp)  # Коэффициент детерминации для квадратичной
 | 
			
		||||
print(f"SSE квадратичной: {SSEp:.2f}, R^2 квадратичной функции: {R2_quad:.3f}")
 | 
			
		||||
 | 
			
		||||
# 6. Построение графиков
 | 
			
		||||
fig, axs = plt.subplots(2, 2, figsize=(14, 10))
 | 
			
		||||
 | 
			
		||||
# Линейная регрессия
 | 
			
		||||
axs[0, 0].scatter(x, Y, facecolors='none', edgecolor='blue', s=40)
 | 
			
		||||
axs[0, 0].plot(x, Y_l, color='red', label=f'Линейная регрессия, R^2 = {R2_lin:.3f}')
 | 
			
		||||
axs[0, 0].set_xlabel('X')
 | 
			
		||||
axs[0, 0].set_ylabel('Y')
 | 
			
		||||
axs[0, 0].set_title('Линейная регрессия')
 | 
			
		||||
axs[0, 0].legend()
 | 
			
		||||
 | 
			
		||||
# Квадратичная регрессия
 | 
			
		||||
axs[0, 1].scatter(xp, Yp, facecolors='none', edgecolor='blue', s=40)
 | 
			
		||||
axs[0, 1].plot(xp, Y_s, color='red', label=f'Квадратичная регрессия, R^2 = {R2_quad:.3f}')
 | 
			
		||||
axs[0, 1].set_xlabel('X')
 | 
			
		||||
axs[0, 1].set_ylabel('Yp')
 | 
			
		||||
axs[0, 1].set_title('Квадратичная регрессия')
 | 
			
		||||
axs[0, 1].legend()
 | 
			
		||||
 | 
			
		||||
# Остатки для линейной регрессии
 | 
			
		||||
residuals_lin = Y - (b0 + b1 * x)
 | 
			
		||||
axs[1, 0].scatter(x, residuals_lin, color='green')
 | 
			
		||||
axs[1, 0].axhline(y=0, color='black', linestyle='--')
 | 
			
		||||
axs[1, 0].set_xlabel('X')
 | 
			
		||||
axs[1, 0].set_ylabel('Остатки')
 | 
			
		||||
axs[1, 0].set_title('Остатки для линейной регрессии')
 | 
			
		||||
 | 
			
		||||
# Остатки для квадратичной регрессии
 | 
			
		||||
residuals_quad = Yp - Y_s
 | 
			
		||||
axs[1, 1].scatter(xp, residuals_quad, color='green')
 | 
			
		||||
axs[1, 1].axhline(y=0, color='black', linestyle='--')
 | 
			
		||||
axs[1, 1].set_xlabel('X')
 | 
			
		||||
axs[1, 1].set_ylabel('Остатки')
 | 
			
		||||
axs[1, 1].set_title('Остатки для квадратичной регрессии')
 | 
			
		||||
 | 
			
		||||
plt.show()
 | 
			
		||||
 | 
			
		||||
# 7. Гистограммы остатков
 | 
			
		||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
 | 
			
		||||
ax1.hist(residuals_lin, bins=20, color='blue', alpha=0.7, edgecolor='black')
 | 
			
		||||
ax1.set_xlabel('Остатки')
 | 
			
		||||
ax1.set_ylabel('Количество')
 | 
			
		||||
ax1.set_title('Гистограмма остатков для линейной регрессии')
 | 
			
		||||
 | 
			
		||||
ax2.hist(residuals_quad, bins=20, color='blue', alpha=0.7, edgecolor='black')
 | 
			
		||||
ax2.set_xlabel('Остатки')
 | 
			
		||||
ax2.set_ylabel('Количество')
 | 
			
		||||
ax2.set_title('Гистограмма остатков для квадратичной регрессии')
 | 
			
		||||
 | 
			
		||||
plt.show()
 | 
			
		||||
 | 
			
		||||
# 8. Тест Голдфельда-Квандта
 | 
			
		||||
def goldfeld_quandt_test(e):
 | 
			
		||||
    n = 500
 | 
			
		||||
    k = 166
 | 
			
		||||
    e1 = e[:k]
 | 
			
		||||
    e3 = e[(n-k):]
 | 
			
		||||
    s1 = np.sum(e1**2)
 | 
			
		||||
    s3 = np.sum(e3**2)
 | 
			
		||||
    f = s3 / s1
 | 
			
		||||
    return f
 | 
			
		||||
 | 
			
		||||
f_lin = goldfeld_quandt_test(residuals_lin)
 | 
			
		||||
f_sqr = goldfeld_quandt_test(residuals_quad)
 | 
			
		||||
 | 
			
		||||
print(f"Статистика F для линейной функции: {f_lin:.3f}")
 | 
			
		||||
print(f"Статистика F для квадратичной функции: {f_sqr:.3f}")
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user