import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Загрузка данных
data = pd.read_csv('Гиперспектр кукурузы.csv', sep=';', decimal=',')
x = data['wavelength'].values
Y = data['Spectr'].values
# Аналитический расчет (нужен для построения красной линии)
a1_analytic = ((x - x.mean()) * (Y - Y.mean())).mean() / ((x - x.mean())**2).mean()
a0_analytic = Y.mean() - a1_analytic * x.mean()
Y_pred_analytic = a0_analytic + a1_analytic * x
# Градиентный спуск (нужен для синей линии и второго графика)
class SimpleRegression:
def __init__(self):
self.a0 = 0.0
self.a1 = 0.0
def predict(self, x):
return self.a0 + self.a1 * x
def MSE(self, x, Y):
return ((self.predict(x) - Y)**2).mean()
def fit(self, x, Y, alpha=0.0000001, max_steps=1000):
steps, errors = [], []
for step in range(max_steps):
y_pred = self.predict(x)
dT_a0 = -2 * (Y - y_pred).mean()
dT_a1 = -2 * ((Y - y_pred) * x).mean()
self.a0 -= alpha * dT_a0
self.a1 -= alpha * dT_a1
errors.append(self.MSE(x, Y))
steps.append(step)
return steps, errors
regr = SimpleRegression()
steps, errors = regr.fit(x, Y, alpha=0.0000001, max_steps=1000)
# Построение 2-х графиков
plt.figure(figsize=(14, 6))
# График 1: Сравнение моделей
plt.subplot(1, 2, 1)
plt.scatter(x, Y, alpha=0.6, s=15, label='Исходные данные', color='gray')
plt.plot(x, Y_pred_analytic, 'r-', linewidth=2, label=f'Аналитическая: Y={a0_analytic:.4f}+{a1_analytic:.4f}*x')
plt.plot(x, regr.predict(x), 'b--', linewidth=2, label=f'Градиентный спуск: Y={regr.a0:.4f}+{regr.a1:.4f}*x')
plt.xlabel('Длина волны (wavelength)')
plt.ylabel('Спектр (Spectr)')
plt.title('Сравнение моделей парной линейной регрессии')
plt.legend()
plt.grid(True, alpha=0.3)
# График 2: Кривая обучения
plt.subplot(1, 2, 2)
plt.plot(steps, errors, 'b-', linewidth=1.5)
plt.xlabel('Номер шага (итерация)')
plt.ylabel('MSE (Среднеквадратичная ошибка)')
plt.title('Кривая обучения метода градиентного спуска')
plt.grid(True, alpha=0.3)
plt.yscale('log')
plt.tight_layout()
plt.show()