import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import Pipeline
from sklearn.decomposition import PCA
import skfuzzy as fuzz

# 成分数据矩阵
data = np.array([[0.758, 0.171, 0.049, 0.022],
                 [0.758, 0.172, 0.047, 0.023],
                 [0.762, 0.17, 0.047, 0.021],
                 [0.762, 0.17, 0.047, 0.021],
                 [0.76, 0.171, 0.047, 0.021],
                 [0.762, 0.166, 0.051, 0.021],
                 [0.761, 0.171, 0.048, 0.02],
                 [0.757, 0.175, 0.049, 0.019],
                 [0.747, 0.182, 0.052, 0.019],
                 [0.75, 0.174, 0.057, 0.019],
                 [0.746, 0.175, 0.061, 0.018],
                 [0.747, 0.18, 0.055, 0.018],
                 [0.715, 0.204, 0.062, 0.017],
                 [0.696, 0.215, 0.067, 0.022],
                 [0.68, 0.232, 0.066, 0.022],
                 [0.661, 0.246, 0.068, 0.025],
                 [0.653, 0.243, 0.077, 0.027],
                 [0.661, 0.234, 0.078, 0.027],
                 [0.702, 0.201, 0.074, 0.023],
                 [0.702, 0.199, 0.076, 0.023],
                 [0.724, 0.178, 0.074, 0.024],
                 [0.724, 0.175, 0.074, 0.027],
                 [0.725, 0.17, 0.075, 0.03],
                 [0.715, 0.167, 0.084, 0.034],
                 [0.716, 0.164, 0.085, 0.035],
                 [0.692, 0.174, 0.094, 0.04],
                 [0.702, 0.168, 0.084, 0.046],
                 [0.685, 0.17, 0.097, 0.048],
                 [0.674, 0.171, 0.102, 0.053],
                 [0.658, 0.173, 0.113, 0.056],
                 [0.638, 0.184, 0.12, 0.058],
                 [0.622, 0.187, 0.13, 0.061],
                 [0.606, 0.189, 0.136, 0.069],
                 [0.59, 0.189, 0.145, 0.076],
                 [0.577, 0.19, 0.153, 0.08],
                 [0.569, 0.188, 0.159, 0.084],
                 [0.559, 0.186, 0.167, 0.088],
                 [0.562, 0.179, 0.175, 0.084]])

# 转换为特征矩阵(LCC方法将1改成234)
feature_matrix = np.zeros((len(data) - 1, len(data[0])))
for i in range(len(data) - 1):
    feature_matrix[i] = data[i + 1] - data[i]

# 构建特征矩阵的DataFrame
df = pd.DataFrame(feature_matrix, columns=['Coal', 'Petroleum', 'Others', 'Gas'])

# 目标变量(LCC方法将1改成234)
target = data[1:, 1]  # 使用第二列作为目标变量

# 数据归一化
scaler = MinMaxScaler()
df_scaled = scaler.fit_transform(df)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(df_scaled, target, test_size=0.13, random_state=42)
class TSK_FS():
    def __init__(self, n_cluster=20, C=0.1):
        '''
        Takagi-Sugeno-Kang Fuzzy System by Yuqi Cui.
        Follow the style of sklearn
        2018/4/7
        :param n_cluster: number of rules /  number of clusters
        :param C: L2 regularization coefficient
        :param method: 'classification' or 'regression', if classification then target should have size of n_Sample * n_Classes
        '''
        self.n_cluster = n_cluster
        self.lamda = C
        self.trained = False

    def fit(self, X_train, y_train):
        '''
        train TSK
        :param X_train: n_Samples * n_Features
        :param y_train: n_Samples * n_Classes or n_Samples * 1 if regression
        :return:
        '''
        n_samples, n_features = X_train.shape
        n_cluster = self.n_cluster
        assert (n_samples == len(y_train)), 'X_train and y_train samples num must be same'
        centers, delta = self.__fcm__(X_train, n_cluster)
        self.centers = centers
        self.delta = delta
        # compute x_g
        xg = self.__gaussian_feature__(X_train, centers, delta)
        # train by pinv
        xg1 = np.dot(xg.T, xg)
        pg = np.linalg.pinv(xg1 + self.lamda * np.eye(xg1.shape[0])).dot(xg.T).dot(y_train)
        # pg = pg.dot(y_train)
        self.pg = pg
        # print(pg)
        self.trained = True

    def predict(self, X_test):
        '''
        predict by test data
        :param X_test: n_Samples * n_Features
        :return: n_Samples * n_Classes or n_Samples * 1 if regression
        '''
        assert(self.trained), 'Error when predict, use fit first!'
        xg_test = self.__gaussian_feature__(X_test, self.centers, self.delta)
        y_pred = xg_test.dot(self.pg)
        return y_pred

    def fcm(self, data, n_cluster):
        return self.__fcm__(data, n_cluster)

    def gaussian_feature(self, data, centers, delta):
        return self.__gaussian_feature__(data, centers, delta)

    def __fcm__(self, data, n_cluster):
        '''
        Comute data centers and membership of each point by FCM, and compute the variance of each feature
        :param data: n_Samples * n_Features
        :param n_cluster: number of center
        :return: centers: data center, delta: variance of each feature
        '''
        n_samples, n_features = data.shape
        centers, mem, _, _, _, _, _ = fuzz.cmeans(
            data.T, n_cluster, 2.0, error=1e-5, maxiter=200)

        # compute delta compute the variance of each feature
        delta = np.zeros([n_cluster, n_features])
        for i in range(n_cluster):
            d = (data - centers[i, :]) ** 2
            delta[i, :] = np.sum(d * mem[i, :].reshape(-1, 1),
                                 axis=0) / np.sum(mem[i, :])

        return centers, delta

    def __gaussian_feature__(self, data, centers, delta):
        '''
        Compute firing strength using Gaussian model
        :param data: n_Samples * n_Features
        :param centers: data center,n_Clusters * n_Features
        :param delta: variance of each feature, n_Clusters * n_Features
        :return: data_fs data的firing strength, n_Samples * [n_Clusters * (n_Features+1)]
        '''
        n_cluster = self.n_cluster
        n_samples = data.shape[0]
        # compute firing strength of each data, n_Samples * n_Clusters
        mu_a = np.zeros([n_samples, n_cluster])
        for i in range(n_cluster):
            tmp_k = 0 - np.sum((data - centers[i, :]) ** 2 /
                               delta[i, :], axis=1)
            mu_a[:, i] = np.exp(tmp_k)  # exp max 709
        # norm
        mu_a = mu_a / np.sum(mu_a, axis=1, keepdims=True)
        # print(np.count_nonzero(mu_a!=mu_a))
        data_1 = np.concatenate((data, np.ones([n_samples, 1])), axis=1)
        zt = []
        for i in range(n_cluster):
            zt.append(data_1 * mu_a[:, i].reshape(-1, 1))
        data_fs = np.concatenate(zt, axis=1)
        data_fs = np.where(data_fs != data_fs, 1e-5, data_fs)
        return data_fs
# 创建TSK模型对象
model = TSK_FS(n_cluster=20, C=0.1)
# 拟合模型
model.fit(X_train, y_train)
# 在测试集上进行预测
y_pred = model.predict(X_test)
# 输出预测结果
print('预测结果:', y_pred)

# 计算CRMSE和CMAPE
crmse = np.sqrt(mean_squared_error(y_test, y_pred))
cmape = np.mean(np.abs((y_test - y_pred) / y_test)) * 100

print('CRMSE:', crmse)
print('CMAPE:', cmape)
# 在测试集上进行预测
y_pred = model.predict(X_test)

# 计算RMSE
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print('RMSE:', rmse)

# 计算MAPE
mape = np.mean(np.abs((y_test - y_pred) / y_test)) * 100
print('MAPE:', mape)

# 计算MDE
mde = np.mean(np.abs(y_test - y_pred))
print('MDE:', mde)
# 构建未来10年的特征矩阵
future_features = np.zeros((10, len(data[0])-1))
current_data = data[-1, :-1]  # 使用最后一行数据作为当前数据

# 根据模型预测未来十年的特征
for i in range(10):
    feature = model.predict(current_data.reshape(1, -1))  # 使用模型预测特征
    future_features[i] = feature  # 更新特征矩阵
    current_data = np.concatenate((current_data[1:], feature))  # 更新当前数据

# 归一化未来的特征数据
future_scaled = scaler.transform(future_features.reshape(-1, len(data[0])-1))

# 使用TSK_FLS模型预测未来十年的目标变量
future_pred = model.predict(future_scaled)

# 计算置信区间
residuals = y_test - y_pred
mean_residuals = np.mean(residuals)
std_residuals = np.std(residuals)
n_samples = len(future_pred)
z_score = 1.96  # 对应于95%的置信区间
margin_of_error = z_score * std_residuals / np.sqrt(n_samples)

lower_bound = future_pred - margin_of_error
upper_bound = future_pred + margin_of_error

# 输出未来十年的预测置信区间
print('未来十年的预测置信区间:')
for i in range(len(future_pred)):
    print(f'年份: {i+1}, 下界: {lower_bound[i]}, 上界: {upper_bound[i]}')

详细介绍TSK-FS方法

TSK-FS(Takagi-Sugeno-Kang Fuzzy System)是一种结合了TSK模型和特征选择方法的模型,用于提高预测性能。

1. TSK模型

TSK模型是基于模糊逻辑的模型,它使用模糊规则来描述输入特征和输出变量之间的关系。在预测过程中,TSK模型根据输入特征的模糊集合和模糊规则计算模糊输出,然后通过去模糊化得到最终的预测结果。

2. 特征选择

TSK-FS模型在TSK模型的基础上添加了特征选择步骤,从原始特征集中选择最相关的特征以提高模型预测性能。特征选择通过使用模糊C均值(FCM)算法来计算特征的重要性,并选择最重要的特征用于建模。

3. TSK-FS模型的训练过程

TSK-FS模型的训练过程包括以下步骤:

  1. **FCM聚类:**使用模糊C均值算法对训练数据进行聚类,得到数据的聚类中心和隶属度矩阵。
  2. **特征选择:**根据聚类结果,计算每个特征的重要性,选择最重要的特征。
  3. **模型训练:**使用选择的特征和聚类结果构建TSK模型,并使用训练数据进行模型训练。
  4. **模型预测:**使用训练好的模型预测目标变量的值。

4. 超参数优化

TSK-FS模型可以通过调整聚类数目和正则化系数等超参数来优化模型的性能。

代码解析

  1. 导入库: 导入所需的库,包括NumPy、Pandas、Scikit-learn和Scikit-fuzzy。
  2. 数据准备: 定义一个包含成分数据的矩阵。
  3. 特征矩阵构建: 将成分数据转换为特征矩阵,通过计算数据之间的差值来构建特征矩阵。
  4. DataFrame创建: 使用Pandas库将特征矩阵转换为DataFrame,并设置列名。
  5. 目标变量定义: 定义目标变量,即预测的目标值。
  6. 数据归一化: 使用MinMaxScaler对数据进行归一化处理。
  7. 训练集和测试集划分: 使用train_test_split将数据分成训练集和测试集。
  8. TSK_FS类: 定义TSK_FS类,用于构建和训练TSK-FS模型。
    • init 初始化TSK-FS模型,设置聚类数目和正则化系数。
    • fit: 训练TSK-FS模型,使用FCM聚类和特征选择方法来选择重要特征,并使用训练数据进行模型训练。
    • predict: 使用训练好的TSK-FS模型对测试数据进行预测。
    • fcm: 使用模糊C均值算法对数据进行聚类。
    • gaussian_feature: 计算每个数据的激发强度,使用高斯模型计算。
  9. 模型创建和训练: 创建TSK_FS模型对象,并使用训练数据进行模型训练。
  10. 预测结果: 使用训练好的模型对测试数据进行预测,并输出预测结果。
  11. 评价指标: 计算RMSE、MAPE和MDE等评价指标来评估模型的预测性能。
  12. 未来预测: 使用模型预测未来10年的特征,并计算预测结果的置信区间。

总结

TSK-FS模型是一种结合了模糊逻辑和特征选择方法的模型,用于提高预测性能。它在时间序列预测、模式识别和控制等领域都有广泛的应用。

希望这篇详细介绍和代码解析能够帮助您理解TSK-FS模型的原理和实现过程。

TSK-FS Fuzzy System for Time Series Prediction: A Detailed Implementation with Python

原文地址: https://www.cveoy.top/t/topic/bcVm 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录