86 lines
3.0 KiB
Python
86 lines
3.0 KiB
Python
import numpy as np
|
|
import skfuzzy as fuzz
|
|
import matplotlib.pyplot as plt
|
|
|
|
# Ãåíåðèðóåì ñèíòåòè÷åñêèé âðåìåííîé ðÿä ñ òåíäåíöèåé
|
|
np.random.seed(42)
|
|
time = np.arange(0, 50)
|
|
trend = 0.5 * time + np.random.normal(0, 2, size=time.shape)
|
|
plt.plot(time, trend, label='Äàííûå âðåìåííîãî ðÿäà')
|
|
plt.xlabel('Âðåìÿ')
|
|
plt.ylabel('Çíà÷åíèå')
|
|
plt.title('Ïðèìåð âðåìåííîãî ðÿäà')
|
|
plt.legend()
|
|
plt.show()
|
|
# Îïðåäåëåíèå óíèâåðñàëüíûõ ìíîæåñòâ äëÿ òåêóùèõ çíà÷åíèé
|
|
value_range = np.linspace(min(trend), max(trend), 100)
|
|
|
|
# Íå÷åòêèå ìíîæåñòâà (òåðìû): 'íèçêèé', 'ñðåäíèé', 'âûñîêèé'
|
|
low = fuzz.trimf(value_range, [min(trend), min(trend), np.median(trend)])
|
|
medium = fuzz.trimf(value_range, [min(trend), np.median(trend), max(trend)])
|
|
high = fuzz.trimf(value_range, [np.median(trend), max(trend), max(trend)])
|
|
|
|
# Âèçóàëèçàöèÿ
|
|
plt.figure()
|
|
plt.plot(value_range, low, label='Íèçêèé')
|
|
plt.plot(value_range, medium, label='Ñðåäíèé')
|
|
plt.plot(value_range, high, label='Âûñîêèé')
|
|
plt.title('Íå÷åòêèå ìíîæåñòâà çíà÷åíèé')
|
|
plt.xlabel('Çíà÷åíèå')
|
|
plt.ylabel('Ïðèíàäëåæíîñòü')
|
|
plt.legend()
|
|
plt.show()
|
|
|
|
|
|
def fuzzy_rule(value):
|
|
# Âû÷èñëÿåì ïðèíàäëåæíîñòè
|
|
low_level = fuzz.interp_membership(value_range, low, value)
|
|
medium_level = fuzz.interp_membership(value_range, medium, value)
|
|
high_level = fuzz.interp_membership(value_range, high, value)
|
|
|
|
# Îïðåäåëÿåì âûâîäíûå ìíîæåñòâà äëÿ òåíäåíöèè
|
|
# Äëÿ ïðîñòîòû, íàçíà÷èì âåðîÿòíîñòíûå âåñà
|
|
decline_weight = low_level
|
|
stable_weight = medium_level
|
|
increase_weight = high_level
|
|
|
|
# Íàõîäèì öåíòð ìàññ äëÿ êàæäîãî âûâîäà
|
|
# Çäåñü ìîæíî ïðèìåíèòü áîëåå ñëîæíûå ìåòîäû
|
|
# Äëÿ ïðèìåðà èñïîëüçóåì ïðîñòîå âçâåøåííîå ñðåäíåå
|
|
trend_centers = {'ïîíèæåíèå': -1, 'ñòàáèëèçàöèÿ': 0, 'ïîâûøåíèå': 1}
|
|
numerator = (decline_weight * trend_centers['ïîíèæåíèå'] +
|
|
stable_weight * trend_centers['ñòàáèëèçàöèÿ'] +
|
|
increase_weight * trend_centers['ïîâûøåíèå'])
|
|
denominator = decline_weight + stable_weight + increase_weight
|
|
if denominator == 0:
|
|
return 0
|
|
return numerator / denominator
|
|
|
|
|
|
# Àíàëèç ïîñëåäíåãî çíà÷åíèÿ
|
|
last_value = trend[-1]
|
|
predicted_trend = fuzzy_rule(last_value)
|
|
|
|
# Ìàñøòàáèðóåì ïðîãíîç
|
|
# Ïðåäïîëîæèì, ÷òî òåíäåíöèÿ âëèÿåò íà ñëåäóþùèé óðîâåíü
|
|
# Ìîæíî äîáàâèòü áîëåå ñëîæíóþ ìîäåëü
|
|
next_value = last_value + predicted_trend # ïðîñòàÿ ìîäåëü
|
|
print(f'Ïîñëåäíåå çíà÷åíèå: {last_value:.2f}')
|
|
print(f'Ïðîãíîçèðóåìîå èçìåíåíèå: {predicted_trend:.2f}')
|
|
print(f'Ñëåäóþùåå çíà÷åíèå: {next_value:.2f}')
|
|
|
|
predictions = []
|
|
current_value = trend[-1]
|
|
for _ in range(10): # ïðîãíîç íà 10 øàãîâ âïåðåä
|
|
trend_estimate = fuzzy_rule(current_value)
|
|
current_value = current_value + trend_estimate
|
|
predictions.append(current_value)
|
|
|
|
# Âèçóàëèçàöèÿ
|
|
plt.plot(range(len(trend)), trend, label='Èñõîäíûå äàííûå')
|
|
plt.plot(range(len(trend), len(trend) + len(predictions)), predictions, label='Ïðîãíîç')
|
|
plt.xlabel('Âðåìÿ')
|
|
plt.ylabel('Çíà÷åíèå')
|
|
plt.legend()
|
|
plt.title('Ïðîãíîçèðîâàíèå ñ ïîìîùüþ íå÷åòêîé ìîäåëè')
|
|
plt.show() |