
- •Министерство цифрового развития, связи и массовых коммуникаций Российской Федерации
- •«Московский технический университет связи и информатики» (мтуси)
- •1 Цель работы
- •Задание
- •3 Краткая теория
- •4 Выполнение лабораторной работы
- •Описание алгоритма определения класса
- •Листинг 1. Программа для классификации объектов
- •5 Выводы
- •Контрольные вопросы
Описание алгоритма определения класса
1. Все входные данные приводятся к диапазону 0-10;
2. Для каждого правила вычисляются значения α (минимум (так как все правила записаны через «И») по значениям функций принадлежностей, входящих в правило (значения функций ищутся путем подстановки входных параметров в соответствующие функции принадлежности)) и z (аргумент выходной функции принадлежности, в котором значение этой функции равняется α);
3. Проводится дефаззификация с использованием алгоритма Цукамото
4. Определяется к какому классу относится точка z0
Важное ограничение: для использования алгоритма Цукамото необходимо, чтобы все функции принадлежности были монотонны.
Результат выполнения алгоритма представлен на рисунке 4:
Рисунок 4 – результат выполнения алгоритма
Полный код программы с пояснениями в виде комментариев представлен в листинге 1.
Листинг 1. Программа для классификации объектов
import numpy as np import mysql.connector from mysql.connector import Error from getpass import getpass
# Функции принадлежности (Гауссовы) def gauss(x, mu, sigma): return np.exp(-((x - mu)**2) / (2 * sigma**2))
# Обратные функции (для алгоритма Цукамото) def inv_gauss(y, mu, sigma): return mu + np.sqrt(-2 * sigma**2 * np.log(y))
# Класс для нечеткой логики class FuzzyDriverClassifier: def __init__(self): self.rules = self._generate_rules()
def _generate_rules(self): """Генерация базы правил""" return [ # Стаж (1-малый, 2-средний, 3-большой), # Возраст (1-молодой, 2-средний, 3-старший), # Рейтинг (1-низкий, 2-средний, 3-высокий), # Класс (1-новичок, 2-опытный, 3-профессионал, 4-эксперт) [1,1,1,1], [1,1,2,2], [1,1,3,2], [1,2,1,1], [1,2,2,2], [1,2,3,3], [1,3,1,1], [1,3,2,2], [1,3,3,2], [2,1,1,2], [2,1,2,2], [2,1,3,3], [2,2,1,2], [2,2,2,3], [2,2,3,3], [2,3,1,2], [2,3,2,3], [2,3,3,4], [3,1,1,3], [3,1,2,3], [3,1,3,4], [3,2,1,3], [3,2,2,4], [3,2,3,4], [3,3,1,3], [3,3,2,4], [3,3,3,4] ]
def _normalize(self, experience, age, rating): """Нормализация к диапазону [0;10]""" exp_norm = float(experience) / 1.5 # [0;10] age_norm = (float(age) - 18) / 3.7 # [18;55] -> [0;10] rating_norm = (float(rating) - 1) * 2.5 # [1;5] -> [0;10] return exp_norm, age_norm, rating_norm
def _fuzzify(self, value, params): """Фаззификация входных значений""" return [gauss(value, mu, sigma) for mu, sigma in params]
def classify(self, experience, age, rating): """Основная функция классификации""" # Нормализация exp_norm, age_norm, rating_norm = self._normalize(experience, age, rating)
# Параметры функций принадлежности (mu, sigma) exp_params = [(0, 3), (5, 3), (10, 3)] # Стаж age_params = [(0, 3), (5, 3), (10, 3)] # Возраст rating_params = [(0, 2.5), (5, 2.5), (10, 2.5)] # Рейтинг
# Фаззификация exp_fuzzy = self._fuzzify(exp_norm, exp_params) age_fuzzy = self._fuzzify(age_norm, age_params) rating_fuzzy = self._fuzzify(rating_norm, rating_params)
# Логический вывод (алгоритм Цукамото) numerator = 0 denominator = 0
for rule in self.rules: # Минимальная степень активации правила alpha = min( exp_fuzzy[rule[0]-1], age_fuzzy[rule[1]-1], rating_fuzzy[rule[2]-1] )
# Вычисление z для выхода if rule[3] == 1: # Новичок z = inv_gauss(alpha, 0, 3) elif rule[3] == 2: # Опытный z = inv_gauss(alpha, 3.33, 3) elif rule[3] == 3: # Профессионал z = inv_gauss(alpha, 6.67, 3) else: # Эксперт z = inv_gauss(alpha, 10, 3)
z = max(0, min(10, z)) # Ограничение [0;10]
numerator += alpha * z denominator += alpha
if denominator == 0: return "Не определено"
# Дефаззификация z0 = numerator / denominator
# Определение класса output_membership = [ gauss(z0, 0, 3), # Новичок gauss(z0, 3.33, 3), # Опытный gauss(z0, 6.67, 3), # Профессионал gauss(z0, 10, 3) # Эксперт ]
classes = ["Новичок", "Опытный", "Профессионал", "Эксперт"] return classes[np.argmax(output_membership)]
# Подключение к базе данных и классификация def main(): try: # Подключение к БД connection = mysql.connector.connect( host="localhost", user=input("Введите имя пользователя MySQL: "), password=getpass("Введите пароль: "), database="сargo_transportation" # Ваша база данных )
cursor = connection.cursor(dictionary=True)
# Получение данных о водителях cursor.execute("SELECT * FROM DRIVERS") drivers = cursor.fetchall()
classifier = FuzzyDriverClassifier()
print("\nРезультаты классификации:") print("------------------------") for driver in drivers: category = classifier.classify( driver['d_experiens'], driver['d_age'], driver['d_rating'] ) print(f"{driver['d_surname']} {driver['d_name']}: {category}")
except Error as e: print(f"Ошибка подключения к MySQL: {e}") finally: if connection.is_connected(): cursor.close() connection.close()
if __name__ == "__main__": main() |