334 KiB
Лабораторная работа №7¶
Столбцы датасета и их пояснение:
Date - Дата, на которую относятся данные. Эта характеристика указывает конкретный день, в который происходила торговля акциями Walmart.
Open - Цена открытия. Стоимость акций Walmart в начале торгового дня. Это важный показатель, который показывает, по какой цене начались торги в конкретный день, и часто используется для сравнения с ценой закрытия для определения дневного тренда.
High - Максимальная цена за день. Наибольшая цена, достигнутая акциями Walmart в течение торгового дня. Эта характеристика указывает, какой была самая высокая стоимость акций за день.
Low - Минимальная цена за день. Наименьшая цена, по которой торговались акции Walmart в течение дня.
Close - Цена закрытия. Стоимость акций Walmart в конце торгового дня. Цена закрытия — один из основных показателей, используемых для анализа акций, так как она отображает итоговую стоимость акций за день и часто используется для расчета дневных изменений и трендов на длительных временных периодах.
Adj Close - Скорректированная цена закрытия. Цена закрытия, скорректированная с учетом всех корпоративных действий.
Volume - Объем торгов. Количество акций Walmart, проданных и купленных в течение дня.
Выгружаем данные
import pandas as pd
df = pd.read_csv("..//static//csv//WMT.csv")
print(df.head())
print(df.columns)
display(df.head(15))
print(df.isnull().sum())
print("\nМаксимальные значения по каждому столбцу:")
print(df.max())
print("\Минимальные значения по каждому столбцу:")
print(df.min())
Выбор входных и выходных переменных¶
Входные переменные будут Open (цена открытия) и Volume (объем торгов)
Выходная переменная - Close (цена закрытия)
Настройка параметров лингвистических переменных¶
Термы: Low, Medium, High
import numpy as np
import matplotlib.pyplot as plt
import skfuzzy as fuzz
# Минимальные и максимальные значения из данных
volume_max = 395500800
# Определяем диапазон значений для объема торгов
volume_range = np.arange(0, volume_max, 10000)
# Определение функций принадлежности для термов
# Определение функций принадлежности для термов
low = fuzz.trapmf(volume_range, [0, 0, 100000000, 150000000])
medium = fuzz.trimf(volume_range, [100000000, 200000000, 300000000])
high = fuzz.trapmf(volume_range, [250000000, 300000000, volume_max, volume_max])
# Визуализация функций принадлежности
plt.figure(figsize=(10, 6))
plt.plot(volume_range, low, label='Низкий (Low)', color='blue')
plt.plot(volume_range, medium, label='Средний (Medium)', color='orange')
plt.plot(volume_range, high, label='Высокий (High)', color='green')
plt.title('Функции принадлежности для объема торгов')
plt.xlabel('Объем торгов')
plt.ylabel('Принадлежность')
plt.ylim(-0.1, 1.1)
plt.axhline(0, color='black', lw=0.5)
plt.axvline(0, color='black', lw=0.5)
plt.legend()
plt.grid()
# Отображаем график
plt.show()
Формирование базы нечетких правил¶
import numpy as np
import skfuzzy as fuzz
import matplotlib.pyplot as plt
# Минимальные и максимальные значения из данных
open_min = 0.005208
open_max = 81.040001
volume_min = 0
close_min = 0.005208
close_max = 81.400002
# Определение диапазонов для переменных
x_open = np.linspace(open_min, open_max, 100) # Диапазон для цены открытия
x_volume = np.linspace(volume_min, volume_max, 100) # Диапазон для объема торгов
x_close = np.linspace(close_min, close_max, 100) # Диапазон для цены закрытия
# Определение функций принадлежности для цены открытия
low_open = fuzz.trapmf(x_open, [open_min, open_min, 20, 40]) # Низкая цена открытия
medium_open = fuzz.trimf(x_open, [30, 50, 70]) # Средняя цена открытия
high_open = fuzz.trapmf(x_open, [60, 70, open_max, open_max]) # Высокая цена открытия
# Определение функций принадлежности для объема торгов
low_volume = fuzz.trapmf(x_volume, [volume_min, volume_min, 100000000, 150000000]) # Низкий объем
medium_volume = fuzz.trimf(x_volume, [100000000, 200000000, 300000000]) # Средний объем
high_volume = fuzz.trapmf(x_volume, [250000000, 300000000, volume_max, volume_max]) # Высокий объем
# Определение функций принадлежности для цены закрытия
low_close = fuzz.trapmf(x_close, [close_min, close_min, 20, 40]) # Низкая цена закрытия
medium_close = fuzz.trimf(x_close, [30, 50, 70]) # Средняя цена закрытия
high_close = fuzz.trapmf(x_close, [60, 70, close_max, close_max]) # Высокая цена закрытия
# Определение нечетких правил
fuzzy_rules = [
("Низкая", "Низкий", "Низкая"),
("Низкая", "Средний", "Средняя"),
("Низкая", "Высокий", "Средняя"),
("Средняя", "Низкий", "Средняя"),
("Средняя", "Средний", "Высокая"),
("Средняя", "Высокий", "Высокая"),
("Высокая", "Низкий", "Средняя"),
("Высокая", "Средний", "Высокая"),
("Высокая", "Высокий", "Высокая"),
]
# Вывод правил
print("Нечеткие правила:")
for rule in fuzzy_rules:
print(f"Если Цена открытия {rule[0]} И Объем {rule[1]}, Тогда Цена закрытия {rule[2]}.")
# Визуализация функций принадлежности
fig, axs = plt.subplots(3, 1, figsize=(10, 12))
# Цена открытия
axs[0].plot(x_open, low_open, label='Низкая (Low)', color='blue')
axs[0].plot(x_open, medium_open, label='Средняя (Medium)', color='green')
axs[0].plot(x_open, high_open, label='Высокая (High)', color='red')
axs[0].set_title('Функции принадлежности для цены открытия')
axs[0].set_xlabel('Цена открытия')
axs[0].set_ylabel('Степень принадлежности')
axs[0].legend()
axs[0].grid()
# Объем торгов
axs[1].plot(x_volume, low_volume, label='Низкий (Low)', color='blue')
axs[1].plot(x_volume, medium_volume, label='Средний (Medium)', color='orange')
axs[1].plot(x_volume, high_volume, label='Высокий (High)', color='green')
axs[1].set_title('Функции принадлежности для объема торгов')
axs[1].set_xlabel('Объем торгов')
axs[1].set_ylabel('Степень принадлежности')
axs[1].legend()
axs[1].grid()
# Цена закрытия
axs[2].plot(x_close, low_close, label='Низкая', color='blue')
axs[2].plot(x_close, medium_close, label='Средняя', color='green')
axs[2].plot(x_close, high_close, label='Высокая', color='red')
axs[2].set_title('Функции принадлежности для цены закрытия')
axs[2].set_xlabel('Цена закрытия')
axs[2].set_ylabel('Степень принадлежности')
axs[2].legend()
axs[2].grid()
plt.tight_layout()
plt.show()
# Визуализация нечетких правил (пример)
fig, ax = plt.subplots(figsize=(10, 6))
x_rule = np.linspace(open_min, open_max, 100)
# Пример нечеткого вывода для визуализации (примерные значения)
for rule in fuzzy_rules:
# Определение степени уверенности для каждого правила
if rule[0] == "Низкая" and rule[1] == "Низкий":
ax.fill_between(x_open, low_open, low_close, color='lightblue', alpha=0.5, label='Низкий #1')
elif rule[0] == "Низкая" and rule[1] == "Средний":
ax.fill_between(x_open, medium_open, medium_close, color='lightgreen', alpha=0.5, label='Средний #2')
elif rule[0] == "Низкая" and rule[1] == "Высокий":
ax.fill_between(x_open, low_open, medium_close, color='lightcoral', alpha=0.5, label='Высокий #3')
elif rule[0] == "Средняя" and rule[1] == "Низкий":
ax.fill_between(x_open, medium_open, medium_close, color='orange', alpha=0.5, label='Низкий #4')
elif rule[0] == "Высокая" and rule[1] == "Высокий":
ax.fill_between(x_open, high_open, high_close, color='salmon', alpha=0.5, label='Высокий #5')
ax.set_title('Визуализация нечетких правил')
ax.set_xlabel('Цена открытия')
ax.set_ylabel('Цена закрытия')
ax.legend()
ax.grid()
plt.tight_layout()
plt.show()
Оценка качества полученной нечеткой системы, используя метрики регрессии¶
import numpy as np
import skfuzzy as fuzz
import matplotlib.pyplot as plt
# Определение диапазонов для переменных
x_open = np.linspace(open_min, open_max, 100) # Диапазон для цены открытия
x_volume = np.linspace(volume_min, volume_max, 100) # Диапазон для объема торгов
x_close = np.linspace(close_min, close_max, 100) # Диапазон для цены закрытия
# Определение функций принадлежности для цены открытия
low_open = fuzz.trapmf(x_open, [open_min, open_min, 20, 40]) # Низкая цена открытия
medium_open = fuzz.trimf(x_open, [30, 50, 70]) # Средняя цена открытия
high_open = fuzz.trapmf(x_open, [60, 70, open_max, open_max]) # Высокая цена открытия
# Определение функций принадлежности для объема торгов
low_volume = fuzz.trapmf(x_volume, [volume_min, volume_min, 100000000, 150000000]) # Низкий объем
medium_volume = fuzz.trimf(x_volume, [100000000, 200000000, 300000000]) # Средний объем
high_volume = fuzz.trapmf(x_volume, [250000000, 300000000, volume_max, volume_max]) # Высокий объем
# Определение функций принадлежности для цены закрытия
low_close = fuzz.trapmf(x_close, [close_min, close_min, 20, 40]) # Низкая цена закрытия
medium_close = fuzz.trimf(x_close, [30, 50, 70]) # Средняя цена закрытия
high_close = fuzz.trapmf(x_close, [60, 70, close_max, close_max]) # Высокая цена закрытия
# Создаем тестовые данные (цена открытия, объем, эталонная цена закрытия)
test_data = [
(20, 100000000, 30), # Низкая цена открытия, низкий объем и цена закрытия
(50, 200000000, 60), # Средняя цена открытия, средний объем и цена закрытия
(70, 300000000, 80), # Высокая цена открытия, высокий объем и цена закрытия
(40, 150000000, 50) # Средняя цена открытия, средний объем и цена закрытия
]
# Функция для вычисления нечеткой оценки
def fuzzy_inference(open_price, volume):
open_low = fuzz.interp_membership(x_open, low_open, open_price)
open_medium = fuzz.interp_membership(x_open, medium_open, open_price)
open_high = fuzz.interp_membership(x_open, high_open, open_price)
volume_low = fuzz.interp_membership(x_volume, low_volume, volume)
volume_medium = fuzz.interp_membership(x_volume, medium_volume, volume)
volume_high = fuzz.interp_membership(x_volume, high_volume, volume)
close_low = np.fmin(open_low, volume_low)
close_medium = np.fmin(open_medium, volume_medium)
close_high = np.fmin(open_high, volume_high)
close0 = fuzz.defuzz(x_close, low_close, 'centroid') * close_low if close_low > 0 else 0
close1 = fuzz.defuzz(x_close, medium_close, 'centroid') * close_medium if close_medium > 0 else 0
close2 = fuzz.defuzz(x_close, high_close, 'centroid') * close_high if close_high > 0 else 0
return max(close0, close1, close2)
# Список для хранения результатов
results = []
# Оценка системы на тестовом наборе данных
for open_price, volume, actual_close in test_data:
inferred_close = fuzzy_inference(open_price, volume)
results.append((open_price, volume, actual_close, inferred_close))
# Вывод результатов
print(f"{'Цена открытия':<18} | {'Объем торгов':<10} | {'Фактическая цена закрытия':<30} | {'Полученная цена закрытия':<30}")
print("=" * 92)
for open_price, volume, actual_close, inferred_close in results:
print(f"{open_price:<18} | {volume:<10} | {actual_close:<30} | {inferred_close:<30.2f}")
# Вычисление метрик качества
actual_closes = [actual for _, _, actual, _ in results]
inferred_closes = [inferred for _, _, _, inferred in results]
mae = np.mean(np.abs(np.array(actual_closes) - np.array(inferred_closes)))
rmse = np.sqrt(np.mean((np.array(actual_closes) - np.array(inferred_closes)) ** 2))
# Вывод метрик
print(f"\nСредняя абсолютная ошибка (MAE): {mae:.2f}")
print(f"Среднеквадратичная ошибка (RMSE): {rmse:.2f}")