395 KiB
395 KiB
Создание лингвистических переменных¶
Входные X: task и target Выходные Y: need
In [28]:
import numpy as np
from skfuzzy import control as ctrl
task = ctrl.Antecedent(np.arange(0, 100, 1), "task")
target = ctrl.Antecedent(np.arange(0, 100, 1), "target")
need = ctrl.Consequent(np.arange(0, 130, 1), "need")
Формирование нечетких переменных для лингвистических переменных и их визуализация¶
In [29]:
import skfuzzy as fuzz
task["less"] = fuzz.zmf(task.universe, 20, 60)
task["ok"] = fuzz.trapmf(task.universe, [10, 30, 60, 80])
task["more"] = fuzz.smf(task.universe, 60, 80)
task.view()
target["less"] = fuzz.zmf(target.universe, 20, 60)
target["ok"] = fuzz.trapmf(target.universe, [10, 30, 60, 80])
target["more"] = fuzz.smf(target.universe, 60, 80)
target.view()
need["less"] = fuzz.zmf(need.universe, 0, 80)
need["ok"] = fuzz.trapmf(need.universe, [0, 60, 70, 90])
need["more"] = fuzz.smf(need.universe, 80, 110)
need.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 [30]:
rule1 = ctrl.Rule(task["less"] & target["more"], need["more"])
rule2 = ctrl.Rule(task["less"] & target["ok"], need["more"])
rule3 = ctrl.Rule(task["less"] & target["less"], need["less"])
rule4 = ctrl.Rule(task["ok"] & target["more"], need["more"])
rule5 = ctrl.Rule(task["ok"] & target["ok"], need["ok"])
rule6 = ctrl.Rule(task["ok"] & target["less"], need["less"])
rule7 = ctrl.Rule(task["more"] & target["more"], need["more"])
rule8 = ctrl.Rule(task["more"] & target["ok"], need["less"])
rule9 = ctrl.Rule(task["more"] & target["less"], need["less"])
rule1.view()
Out[30]:
Создание нечеткой системы и добавление нечетких правил в базу знаний нечеткой системы¶
In [31]:
need_ctrl = ctrl.ControlSystem(
[
rule1,
rule2,
rule3,
rule4,
rule5,
rule6,
rule7,
rule8,
rule9,
]
)
needs = ctrl.ControlSystemSimulation(need_ctrl)
Пример расчета выходной переменной influx на основе входных переменных level и flow¶
Система также формирует подробный журнал выполнения процесса нечеткого логического вывода
In [32]:
needs.input["task"] = 60
needs.input["target"] = 20
needs.compute()
needs.print_state()
needs.output["need"]
Out[32]:
Визуализация функции принадлежности для выходной переменной influx¶
Функция получена в процессе аккумуляции и используется для дефаззификации значения выходной переменной influx
In [33]:
need.view(sim=needs)
Пример решения задачи регрессии на основе нечеткого логического вывода¶
Загрузка данных¶
In [ ]:
import pandas as pd
from utils import split_stratified_into_train_val_test
import numpy as np
import skfuzzy as fuzz
import skfuzzy.control as ctrl
# Загрузка и обработка данных
df = pd.read_csv("data/kc_house_data.csv")
df = df.drop(["id", "date", "lat", "long"], axis=1)
df = df.dropna()
# Разбиение на обучающую, валидационную и тестовую выборки
houses_train, X_val, houses_test, y_train, y_val, y_test = split_stratified_into_train_val_test(
df,
stratify_colname="zipcode", # Стратификация по району
target_colname="price",
frac_train=0.80,
frac_val=0,
frac_test=0.20
)
# Удаляем столбец стратификации
houses_train = houses_train.drop("zipcode", axis=1)
houses_test = houses_test.drop("zipcode", axis=1)
display("houses_train", houses_train)
display("houses_test", houses_test)
Инициализация лингвистических переменных и автоматическое формирование нечетких переменных¶
In [35]:
# Определение нечетких переменных
yr_built = ctrl.Antecedent(np.arange(1900, 2025, 1), "yr_built")
sqft_living = ctrl.Antecedent(houses_train["sqft_living"].sort_values().unique(), "sqft_living")
print(houses_train["price"].max())
price = ctrl.Consequent(np.arange(houses_train["price"].min() // 1000,
houses_train["price"].max() // 1000, 1), "price")
# Размытие переменных
yr_built["old"] = fuzz.zmf(yr_built.universe, 1900, 2000)
yr_built["new"] = fuzz.smf(yr_built.universe, 1990, 2025)
yr_built.view()
sqft_living.automf(3, variable_type="quant")
sqft_living.view()
price["very cheap"] = fuzz.trimf(price.universe, [0, 200, 400])
price["cheap"] = fuzz.trimf(price.universe, [300, 500, 800])
price["average"] = fuzz.trapmf(price.universe, [600, 900, 1500, 2500])
price["expensive"] = fuzz.trimf(price.universe, [2000, 3500, 5000])
price["very expensive"] = fuzz.smf(price.universe, 4000, 10000)
price.view()
Нечеткие правила¶
In [36]:
# Создание правил
rule11 = ctrl.Rule(
sqft_living["low"] & yr_built["old"],
price["very cheap"],
)
rule12 = ctrl.Rule(
sqft_living["average"] & yr_built["old"],
price["cheap"],
)
rule13 = ctrl.Rule(
sqft_living["high"] & yr_built["old"],
price["average"],
)
rule21 = ctrl.Rule(
sqft_living["low"] & yr_built["new"],
price["average"],
)
rule22 = ctrl.Rule(
sqft_living["average"] & yr_built["new"],
price["expensive"],
)
rule23 = ctrl.Rule(
sqft_living["high"] & yr_built["new"],
price["very expensive"],
)
Создание нечеткой системы¶
In [37]:
fuzzy_rules = [
rule11,
rule12,
rule13,
rule21,
rule22,
rule23,
]
price_cntrl = ctrl.ControlSystem(fuzzy_rules)
sim = ctrl.ControlSystemSimulation(price_cntrl)
fuzzy_rules
Out[37]:
Пример использования полученной нечеткой системы¶
In [43]:
# Пример предсказания
sim.input["yr_built"] = 2016
sim.input["sqft_living"] = 1500
sim.compute()
sim.print_state()
display(sim.output["price"])
Функция для автоматизации вычисления целевой переменной Y на основе вектора признаков X¶
In [39]:
# Функция предсказания
def fuzzy_pred(row):
sim.input["yr_built"] = row["yr_built"]
sim.input["sqft_living"] = row["sqft_living"]
sim.compute()
return sim.output["price"]
Тестирование нечеткой системы на обучающей выборке¶
In [40]:
# Применение к обучающим данным
result_train = houses_train.copy()
result_train["PricePred"] = result_train.apply(fuzzy_pred, axis=1)
result_train.head(15)
Out[40]:
Тестирование нечеткой системы на тестовой выборке¶
In [41]:
result_test = houses_test.copy()
result_test["PricePred"] = result_test.apply(fuzzy_pred, axis=1)
result_test["PricePred"] = result_test["PricePred"].apply(lambda x: x)
display(result_test)
Оценка результатов на основе метрик для задачи регрессии¶
In [42]:
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[42]: