303 KiB
303 KiB
импортируем либы¶
In [221]:
import pandas as pd
import re
import numpy as np
import skfuzzy as fuzz
import skfuzzy.control as ctrl
import matplotlib.pyplot as plt
загржаем данные¶
In [222]:
df = pd.read_csv("..//static//csv//car_price_prediction.csv", sep=",")
df.head()
Out[222]:
небольшая обработка данных¶
In [223]:
df['Mileage'] = df['Mileage'].str.replace(' km', '').str.replace(',', '')
df['Mileage'] = df['Mileage'].astype(int)
df['Engine volume'] = df['Engine volume'].apply(lambda x: float(re.match(r'\d+(\.\d+)?', x).group()) if isinstance(x, str) else x)
df.head()
Out[223]:
Выбор входных и выходных переменных¶
Перед тем как строить нечеткую систему, нужно определить, какие переменные будут входными, а какие – выходными.
Входные переменные (fuzzy inputs):¶
- Prod. year (год выпуска) – влияет на цену машины.
- Mileage (пробег) – чем выше пробег, тем дешевле машина.
Выходная переменная (fuzzy output):¶
- Price (цена) – оцениваемая стоимость автомобиля.
Настройка лингвистических переменных¶
Определяем, какие термы будут у каждой переменной, их тип (например, треугольные или гауссовые функции принадлежности) и параметры.
Продолжительность эксплуатации (Prod. year)¶
- Старый (Old)
- Средний (Medium)
- Новый (New)
Пробег (Mileage)¶
- Маленький (Low)
- Средний (Medium)
- Большой (High)
Цена (Price)¶
- Дешевая (Cheap)
- Средняя (Medium)
- Дорогая (Expensive)
In [224]:
pryMin, pryMax = df['Prod. year'].quantile(0.01), df['Prod. year'].quantile(0.97)
milMin, milMax = df['Mileage'].quantile(0.01), df['Mileage'].quantile(0.80)
priMin, priMax = df['Price'].quantile(0.01), df['Price'].quantile(0.97)
# Определяем диапазоны переменных
prod_year = np.arange(pryMin, pryMax, 1) # Годы выпуска
mileage = np.arange(milMin, milMax, 1) # Пробег
price = np.arange(priMin, priMax, 1) # Цена
# Определение переменных
prod_year_ctrl = ctrl.Antecedent(prod_year, 'prod_year')
mileage_ctrl = ctrl.Antecedent(mileage, 'mileage')
price_ctrl = ctrl.Consequent(price, 'price')
Настраиваем функции принадлежности¶
In [225]:
# Функции принадлежности
pryMid = (pryMin+pryMax)/2
prod_year_ctrl['old'] = fuzz.trimf(prod_year, [pryMin, pryMin, pryMax])
prod_year_ctrl['medium'] = fuzz.trimf(prod_year, [pryMin, pryMid, pryMax])
prod_year_ctrl['new'] = fuzz.trimf(prod_year, [pryMin, pryMax, pryMax])
milMid = (milMin+milMax)/2
mileage_ctrl['low'] = fuzz.trimf(mileage, [milMin, milMin, milMax])
mileage_ctrl['medium'] = fuzz.trimf(mileage, [milMin, milMid, milMax])
mileage_ctrl['high'] = fuzz.trimf(mileage, [milMin, milMax, milMax])
priMid = (priMin+priMax)/2
price_ctrl['cheap'] = fuzz.trimf(price, [priMin, priMin, priMax])
price_ctrl['medium'] = fuzz.trimf(price, [priMin, priMid, priMax])
price_ctrl['expensive'] = fuzz.trimf(price, [priMin, priMax, priMax])
# визуализируем
prod_year_ctrl.view()
mileage_ctrl.view()
price_ctrl.view()
In [226]:
# Определение правил
rule1 = ctrl.Rule(prod_year_ctrl['old'] & mileage_ctrl['high'], price_ctrl['cheap'])
rule2 = ctrl.Rule(prod_year_ctrl['medium'] & mileage_ctrl['medium'], price_ctrl['medium'])
rule3 = ctrl.Rule(prod_year_ctrl['new'] & mileage_ctrl['low'], price_ctrl['expensive'])
# Создаем систему
price_control = ctrl.ControlSystem([rule1, rule2, rule3])
price_simulation = ctrl.ControlSystemSimulation(price_control)
In [227]:
price_control.view()
Оценка качества нечеткой системы¶
Чтобы проверить работу модели, можно подать тестовые данные и посмотреть, как система определяет цену.
In [228]:
# Выбираем случайные 10 записей для тестирования
sample_df = df[['Prod. year', 'Mileage', 'Price']].sample(10, random_state=42)
sample_df = sample_df.reset_index(drop=True)
predicted_prices = []
for i in range(len(sample_df)):
price_simulation.input['prod_year'] = sample_df.loc[i, 'Prod. year']
price_simulation.input['mileage'] = sample_df.loc[i, 'Mileage']
price_simulation.compute()
a = price_simulation.print_state()
predicted_prices.append(price_simulation.output['price'])
sample_df['Predicted Price'] = predicted_prices
sample_df_sorted = sample_df.sort_values(by='Price')
# Вывод результатов
print(sample_df_sorted[['Prod. year', 'Mileage', 'Price', 'Predicted Price']])
# Визуализация
plt.figure(figsize=(10, 5))
plt.plot(sample_df.index, sample_df_sorted['Price'], marker='o', label='Real Price', color='blue')
plt.plot(sample_df.index, sample_df_sorted['Predicted Price'], marker='s', label='Predicted Price', color='red')
plt.xlabel("Sample Index")
plt.ylabel("Price")
plt.legend()
plt.title("Сравнение реальных и предсказанных цен")
plt.show()
Система ужасно предсказывает цену, не может предсказать ни большую цену ни маленькую, потому что она хорошо предсказывает категорию, но цену по категории не может