319 KiB
319 KiB
Управление каденсом велосипедиста¶
Создание лингвистических переменных¶
Входные X: speed (текущая скорость) и target (желаемая скорость) / Выходные Y: cadence (необходимый каденс)
In [1]:
import numpy as np
from skfuzzy import control as ctrl
speed = ctrl.Antecedent(np.arange(0, 100, 1), "speed")
target = ctrl.Antecedent(np.arange(0, 100, 1), "target")
cadence = ctrl.Consequent(np.arange(0, 130, 1), "cadence")
Формирование нечетких переменных для лингвистических переменных и их визуализация¶
In [2]:
import skfuzzy as fuzz
speed["slow"] = fuzz.zmf(speed.universe, 20, 60)
speed["average"] = fuzz.trapmf(speed.universe, [10, 30, 60, 80])
speed["fast"] = fuzz.smf(speed.universe, 60, 80)
speed.view()
target["slow"] = fuzz.zmf(target.universe, 20, 60)
target["average"] = fuzz.trapmf(target.universe, [10, 30, 60, 80])
target["fast"] = fuzz.smf(target.universe, 60, 80)
target.view()
cadence["low"] = fuzz.zmf(cadence.universe, 0, 80)
cadence["average"] = fuzz.trapmf(cadence.universe, [0, 60, 70, 90])
cadence["high"] = fuzz.smf(cadence.universe, 80, 110)
cadence.view()
Формирование и визуализация базы нечетких правил¶
В случае ошибки необходимо в файле
.venv/lib/python3.13/site-packages/skfuzzy/control/visualization.py
удалить лишний отступ на 182 строке, должно быть:
if not matplotlib_present:
raise ImportError("`ControlSystemVisualizer` can only be used "
"with `matplotlib` present in the system.")
self.ctrl = control_system
self.fig, self.ax = plt.subplots()
In [3]:
rule1 = ctrl.Rule(speed["slow"] & target["fast"], cadence["high"])
rule2 = ctrl.Rule(speed["slow"] & target["average"], cadence["high"])
rule3 = ctrl.Rule(speed["slow"] & target["slow"], cadence["low"])
rule4 = ctrl.Rule(speed["average"] & target["fast"], cadence["high"])
rule5 = ctrl.Rule(speed["average"] & target["average"], cadence["average"])
rule6 = ctrl.Rule(speed["average"] & target["slow"], cadence["low"])
rule7 = ctrl.Rule(speed["fast"] & target["fast"], cadence["high"])
rule8 = ctrl.Rule(speed["fast"] & target["average"], cadence["low"])
rule9 = ctrl.Rule(speed["fast"] & target["slow"], cadence["low"])
rule1.view()
Out[3]:
Создание нечеткой системы и добавление нечетких правил в базу знаний нечеткой системы¶
In [4]:
cadence_ctrl = ctrl.ControlSystem(
[
rule1,
rule2,
rule3,
rule4,
rule5,
rule6,
rule7,
rule8,
rule9,
]
)
cadences = ctrl.ControlSystemSimulation(cadence_ctrl)
Пример расчета выходной переменной cadence на основе входных переменных speed и target¶
Система также формирует подробный журнал выполнения процесса нечеткого логического вывода
In [5]:
cadences.input["speed"] = 60
cadences.input["target"] = 20
cadences.compute()
cadences.print_state()
cadences.output["cadence"]
Out[5]:
Визуализация функции принадлежности для выходной переменной cadence¶
Функция получена в процессе аккумуляции и используется для дефаззификации значения выходной переменной cadence
In [6]:
cadence.view(sim=cadences)
Пример решения задачи регрессии на основе нечеткого логического вывода¶
Загрузка данных¶
In [7]:
import pandas as pd
from utils import split_stratified_into_train_val_test
df = pd.read_csv("data/car_price_prediction.csv")
df = df.drop(["ID", "Manufacturer", "Model", "Leatherinterior", "Fueltype", "Cylinders",
"Doors", "Wheel", "Color", "Levy", "Drive wheels", "Airbags", "Gear box type", "Mileage"], axis=1)
df = df.dropna()
df["Engine volume"] = df["Engine volume"].apply(
lambda x: float(x.split()[0])
)
cars_train, X_val, cars_test, y_train, y_val, y_test = split_stratified_into_train_val_test(
df,
stratify_colname="Category",
target_colname="Price",
frac_train=0.80,
frac_val=0,
frac_test=0.20
)
cars_train = cars_train.drop("Category", axis=1)
cars_test = cars_test.drop("Category", axis=1)
display("cars_train", cars_train)
display("cars_test", cars_test)
Инициализация лингвистических переменных и автоматическое формирование нечетких переменных¶
In [8]:
prodyear = ctrl.Antecedent(np.arange(1885, 2025, 1), "prodyear")
engine_volume = ctrl.Antecedent(cars_train["Engine volume"].sort_values().unique(), "engine_volume")
print(cars_train["Price"].max())
price = ctrl.Consequent(np.arange(cars_train["Price"].min() // 100,
cars_train["Price"].max() // 100, 1), "price")
prodyear["old"] = fuzz.zmf(prodyear.universe, 1885, 2020)
prodyear["new"] = fuzz.smf(prodyear.universe, 2015, 2020)
prodyear.view()
engine_volume.automf(3, variable_type="quant")
engine_volume.view()
price["very cheap"] = fuzz.trimf(price.universe, [0, 50, 100])
price["cheap"] = fuzz.trimf(price.universe, [80, 120, 200])
price["average"] = fuzz.trapmf(price.universe, [150, 250, 500, 1000])
price["expensive"] = fuzz.trimf(price.universe, [800, 1500, 2000])
price["very expensive"] = fuzz.smf(price.universe, 1800, 2500)
price.view()
Нечеткие правила¶
In [9]:
rule11 = ctrl.Rule(
engine_volume["low"] & prodyear["old"],
price["very cheap"],
)
rule12 = ctrl.Rule(
engine_volume["average"] & prodyear["old"],
price["cheap"],
)
rule13 = ctrl.Rule(
engine_volume["high"] & prodyear["old"],
price["average"],
)
rule21 = ctrl.Rule(
engine_volume["low"] & prodyear["new"],
price["average"],
)
rule22 = ctrl.Rule(
engine_volume["average"] & prodyear["new"],
price["expensive"],
)
rule23 = ctrl.Rule(
engine_volume["high"] & prodyear["new"],
price["very expensive"],
)
Создание нечеткой системы¶
In [10]:
fuzzy_rules = [
rule11,
rule12,
rule13,
rule21,
rule22,
rule23,
]
price_cntrl = ctrl.ControlSystem(fuzzy_rules)
sim = ctrl.ControlSystemSimulation(price_cntrl)
fuzzy_rules
Out[10]:
Пример использования полученной нечеткой системы¶
In [11]:
sim.input["prodyear"] = 2016
sim.input["engine_volume"] = 1.5
sim.compute()
sim.print_state()
display(sim.output["price"])
Функция для автоматизации вычисления целевой переменной Y на основе вектора признаков X¶
In [12]:
def fuzzy_pred(row):
sim.input["prodyear"] = row["Prodyear"]
sim.input["engine_volume"] = row["Engine volume"]
sim.compute()
return sim.output["price"]
Тестирование нечеткой системы на обучающей выборке¶
In [13]:
result_train = cars_train.copy()
result_train["PricePred"] = result_train.apply(fuzzy_pred, axis=1)
result_train.head(15)
Out[13]:
Тестирование нечеткой системы на тестовой выборке¶
In [14]:
result_test = cars_test.copy()
result_test["PricePred"] = result_test.apply(fuzzy_pred, axis=1)
result_test["PricePred"] = result_test["PricePred"].apply(lambda x: x * 100)
display(result_test)
Оценка результатов на основе метрик для задачи регрессии¶
In [15]:
import math
from sklearn import metrics
rmetrics = {}
rmetrics["RMSE_train"] = math.sqrt(
metrics.mean_squared_error(result_test["Price"], result_test["PricePred"])
)
rmetrics["RMSE_test"] = math.sqrt(
metrics.mean_squared_error(result_test["Price"], result_test["PricePred"])
)
rmetrics["RMAE_test"] = math.sqrt(
metrics.mean_absolute_error(result_test["Price"], result_test["PricePred"])
)
rmetrics["R2_test"] = metrics.r2_score(
result_test["Price"], result_test["PricePred"]
)
rmetrics
Out[15]: