some changes

This commit is contained in:
Anton Romanov 2025-04-25 13:21:46 +04:00
parent 2b66b540ef
commit 3199ce93bd
11 changed files with 343 additions and 0 deletions

190
PA/code/fyzzy rules.py Normal file
View File

@ -0,0 +1,190 @@
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from skfuzzy import cmeans, defuzz
from sklearn.linear_model import LinearRegression
# Çàãðóçêà äàííûõ (ïðèìåð ñ äàííûìè î òåìïåðàòóðå)
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-min-temperatures.csv"
data = pd.read_csv(url, header=0, index_col=0, parse_dates=True)
ts_data = data['Temp'].values.reshape(-1, 1)
# Íîðìàëèçàöèÿ äàííûõ
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(ts_data).flatten()
# Ïàðàìåòðû íå÷åòêîé ñèñòåìû
n_clusters = 3 # Êîëè÷åñòâî íå÷åòêèõ ìíîæåñòâ
m = 2.0 # Ïàðàìåòð íå÷åòêîñòè (îáû÷íî ìåæäó 1.5 è 3.0)
max_iter = 100 # Ìàêñèìàëüíîå ÷èñëî èòåðàöèé
error = 0.005 # Êðèòåðèé îñòàíîâà
# Ïðèìåíåíèå íå÷åòêîé c-ñðåäíåé êëàñòåðèçàöèè
cntr, u, u0, d, jm, p, fpc = cmeans(
data=scaled_data.reshape(1, -1),
c=n_clusters,
m=m,
error=error,
maxiter=max_iter
)
# Âèçóàëèçàöèÿ ôóíêöèé ïðèíàäëåæíîñòè
x = np.linspace(0, 1, 100)
plt.figure(figsize=(10, 6))
for i in range(n_clusters):
membership = np.exp(-(x - cntr[i])**2 / (2 * 0.1**2)) # Ãàóññîâà ôóíêöèÿ ïðèíàäëåæíîñòè
plt.plot(x, membership, label=f'Êëàñòåð {i+1}')
plt.title('Ôóíêöèè ïðèíàäëåæíîñòè íå÷åòêèõ ìíîæåñòâ')
plt.xlabel('Íîðìàëèçîâàííîå çíà÷åíèå òåìïåðàòóðû')
plt.ylabel('Ñòåïåíü ïðèíàäëåæíîñòè')
plt.legend()
plt.show()
# Ôóíêöèÿ äëÿ îïðåäåëåíèÿ ïðèíàäëåæíîñòè ê êëàñòåðàì
def get_cluster_membership(x, cntr):
distances = [np.abs(x - c) for c in cntr]
memberships = [1 / (1 + d ** 2) for d in distances] # Èñïîëüçóåì îáðàòíîå ðàññòîÿíèå
return memberships / np.sum(memberships) # Íîðìàëèçàöèÿ
# Ñîçäàíèå îáó÷àþùåãî íàáîðà äëÿ ïðàâèë
window_size = 3 # Ðàçìåð îêíà äëÿ âðåìåííûõ ïàòòåðíîâ
X = []
y = []
for i in range(window_size, len(scaled_data)):
# Ïîëó÷àåì îêíî äàííûõ
window = scaled_data[i - window_size:i]
# Âû÷èñëÿåì ïðèíàäëåæíîñòè äëÿ êàæäîãî ýëåìåíòà îêíà
memberships = np.array([get_cluster_membership(x, cntr) for x in window])
# Íàõîäèì äîìèíèðóþùèé êëàñòåð äëÿ êàæäîãî ýëåìåíòà
dominant_clusters = np.argmax(memberships, axis=1)
# Ôîðìèðóåì ïðàâèëî è öåëåâóþ ïåðåìåííóþ
X.append(dominant_clusters)
y.append(scaled_data[i])
X = np.array(X)
y = np.array(y)
# Èçâëå÷åíèå ÷àñòûõ ïðàâèë
from collections import defaultdict
rule_counts = defaultdict(int)
rule_consequences = defaultdict(list)
for pattern, consequence in zip(X, y):
#rule_key = tuple(pattern)
rule_key = tuple(tuple(row) for row in pattern)
rule_counts[rule_key] += 1
rule_consequences[rule_key].append(consequence)
# Âûâîä íàèáîëåå ÷àñòûõ ïðàâèë
print("Òîï-5 íàèáîëåå ÷àñòûõ ïðàâèë:")
sorted_rules = sorted(rule_counts.items(), key=lambda x: -x[1])[:5]
for rule, count in sorted_rules:
avg_consequence = np.mean(rule_consequences[rule])
print(f"Åñëè {rule} òî y={avg_consequence:.3f} (âñòðå÷àåòñÿ {count} ðàç)")
class FuzzyTSKSystem:
def __init__(self, n_clusters, window_size, cntr):
self.n_clusters = n_clusters
self.window_size = window_size
self.cntr = cntr
self.rules = {}
self.rule_weights = {}
def add_rule(self, antecedent, consequent_func):
self.rules[antecedent] = consequent_func
self.rule_weights[antecedent] = 1.0 # Íà÷àëüíûé âåñ ïðàâèëà
def predict(self, window):
# Âû÷èñëÿåì ïðèíàäëåæíîñòè äëÿ êàæäîãî ýëåìåíòà îêíà
memberships = np.array([get_cluster_membership(x, self.cntr) for x in window])
# Âû÷èñëÿåì àêòèâàöèþ êàæäîãî ïðàâèëà
rule_activations = {}
total_activation = 0.0
for rule_antecedent in self.rules:
# Âû÷èñëÿåì ñòåïåíü ñîîòâåòñòâèÿ îêíà ïðàâèëó
activation = 1.0
for i in range(self.window_size):
cluster = rule_antecedent[i]
activation *= memberships[i, cluster]
rule_activations[rule_antecedent] = activation * self.rule_weights[rule_antecedent]
total_activation += rule_activations[rule_antecedent]
# Åñëè íè îäíî ïðàâèëî íå àêòèâèðîâàíî, âîçâðàùàåì ñðåäíåå
if total_activation == 0:
return np.mean(window)
# Âû÷èñëÿåì âçâåøåííûé âûâîä
weighted_output = 0.0
for rule_antecedent, activation in rule_activations.items():
# Ïîëó÷àåì âûâîä ïðàâèëà (ëèíåéíàÿ ôóíêöèÿ îò âõîäà)
consequent = self.rules[rule_antecedent](window)
weighted_output += activation * consequent
return weighted_output / total_activation
# Ñîçäàåì è îáó÷àåì íå÷åòêóþ ñèñòåìó
fuzzy_system = FuzzyTSKSystem(n_clusters, window_size, cntr)
# Äîáàâëÿåì ïðàâèëà íà îñíîâå äàííûõ
for rule_antecedent in rule_counts:
# Äëÿ êàæäîãî ïðàâèëà ñîçäàåì ëèíåéíóþ ìîäåëü
X_rule = []
y_rule = []
for i in range(len(X)):
if tuple(X[i]) == rule_antecedent:
X_rule.append(scaled_data[i - window_size:i])
y_rule.append(y[i])
"""
if len(X_rule) > 0:
X_rule = np.array(X_rule)
y_rule = np.array(y_rule)
# Îáó÷àåì ëèíåéíóþ ðåãðåññèþ äëÿ ýòîãî ïðàâèëà
model = LinearRegression()
model.fit(X_rule, y_rule)
# Äîáàâëÿåì ïðàâèëî â ñèñòåìó
fuzzy_system.add_rule(
rule_antecedent,
lambda x, m=model: m.predict([x])[0]
)
"""
# Ïðîãíîçèðîâàíèå íà òåñòîâûõ äàííûõ
test_size = 100
train_data = scaled_data[:-test_size]
test_data = scaled_data[-test_size:]
predictions = []
for i in range(window_size, len(test_data)):
window = test_data[i - window_size:i]
pred = fuzzy_system.predict(window)
predictions.append(pred)
# Âèçóàëèçàöèÿ ðåçóëüòàòîâ
plt.figure(figsize=(12, 6))
plt.plot(test_data[window_size:], label='Ôàêòè÷åñêèå çíà÷åíèÿ')
plt.plot(predictions, label='Ïðîãíîç íå÷åòêîé ñèñòåìû')
plt.title('Ñðàâíåíèå ôàêòè÷åñêèõ è ïðîãíîçèðóåìûõ çíà÷åíèé')
plt.legend()
plt.show()
# Îöåíêà êà÷åñòâà ïðîãíîçà
from sklearn.metrics import mean_squared_error
mse = mean_squared_error(test_data[window_size:], predictions)
print(f"Ñðåäíåêâàäðàòè÷íàÿ îøèáêà (MSE): {mse:.5f}")

86
PA/code/fyzzy tendency.py Normal file
View File

@ -0,0 +1,86 @@
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()

67
PA/code/fyzzy.py Normal file
View File

@ -0,0 +1,67 @@
import numpy as np
import skfuzzy as fuzz
import matplotlib.pyplot as plt
# Ãåíåðèðóåì ïðèìåð âðåìåííîãî ðÿäà ñ òðåíäîì è øóìîì
np.random.seed(42)
time = np.arange(0, 50)
data = 0.5 * time + np.random.normal(0, 2, size=time.shape)
plt.plot(time, data, label='Èñõîäíûé ðÿä')
plt.xlabel('Âðåìÿ')
plt.ylabel('Çíà÷åíèå')
plt.legend()
plt.show()
# Ïðåäïîëîæèì, ÷òî ìû èñïîëüçóåì 1 çàäåðæêó (ïðåäûäóùèé ìîìåíò âðåìåíè)
# Ñîçäàåì ìàññèâ âõîäíûõ äàííûõ
input_data = data[:-1]
target_data = data[1:]
# Îïðåäåëèì äèàïàçîí äëÿ âõîäíûõ äàííûõ
x = np.linspace(min(input_data), max(input_data), 100)
# Ñîçäàåì íå÷åòêèå ìíîæåñòâà äëÿ âõîäíûõ äàííûõ
low = fuzz.trimf(x, [min(input_data), min(input_data), np.mean(input_data)])
medium = fuzz.trimf(x, [np.min(input_data), np.mean(input_data), np.max(input_data)])
high = fuzz.trimf(x, [np.mean(input_data), np.max(input_data), np.max(input_data)])
# Âèçóàëèçèðóåì
plt.figure()
plt.plot(x, low, label='Íèçêèé')
plt.plot(x, medium, label='Ñðåäíèé')
plt.plot(x, high, label='Âûñîêèé')
plt.legend()
plt.title('Ôóíêöèè ïðèíàäëåæíîñòè äëÿ âõîäíûõ äàííûõ')
plt.show()
def fuzzy_predict(prev_value, x, low, medium, high):
# Âû÷èñëÿåì ñòåïåíè ïðèíàäëåæíîñòè
mu_low = fuzz.interp_membership(x, low, prev_value)
mu_medium = fuzz.interp_membership(x, medium, prev_value)
mu_high = fuzz.interp_membership(x, high, prev_value)
# Ïðàâèëà
# Ïðåäïîëîæèì, ÷òî ïðîãíîç — âçâåøåííîå ñðåäíåå
# Äëÿ ïðîñòîòû
forecast = (
mu_low * np.mean(target_data) +
mu_medium * np.mean(target_data) +
mu_high * np.mean(target_data)
) / (mu_low + mu_medium + mu_high + 1e-6) # èçáåãàåì äåëåíèÿ íà íîëü
return forecast
# Ïðîãíîçèðóåì ñëåäóþùèé ðÿä
predicted = []
for val in input_data:
pred = fuzzy_predict(val, x, low, medium, high)
predicted.append(pred)
# Âèçóàëèçàöèÿ
plt.plot(time[1:], target_data, label='Ðåàëüíûå äàííûå')
plt.plot(time[1:], predicted, label='Ïðîãíîç íå÷åòêîé ñèñòåìû')
plt.xlabel('Âðåìÿ')
plt.ylabel('Çíà÷åíèå')
plt.legend()
plt.title('Ïðîãíîçèðîâàíèå ñ ïîìîùüþ íå÷åòêîé ñèñòåìû')
plt.show()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.