python实现灰色预测模型与灰色关联分析

转载并整理自:
https://www.codenong.com/p12366364/
https://www.codenong.com/p12368419/

灰色关联度分析

# -*- coding: utf-8 -*-
from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np
import os


class GraModel():
    '''灰色关联度分析模型'''

    def __init__(self, inputData, p=0.5, standard=True):
        '''
        初始化参数
        inputData:输入矩阵,纵轴为属性名,第一列为母序列
        p:分辨系数,范围0~1,一般取0.5,越小,关联系数间差异越大,区分能力越强
        standard:是否需要标准化
        '''
        self.inputData = np.array(inputData)
        self.p = p
        self.standard = standard
        # 标准化
        self.standarOpt()
        # 建模
        self.buildModel()

    def standarOpt(self):
        '''标准化输入数据'''
        if not self.standard:
            return None
        self.scaler = StandardScaler().fit(self.inputData)
        self.inputData = self.scaler.transform(self.inputData)

    def buildModel(self):
        # 第一列为母列,与其他列求绝对差
        momCol = self.inputData[:, 0]
        sonCol = self.inputData[:, 0:]
        for col in range(sonCol.shape[1]):
            sonCol[:, col] = abs(sonCol[:, col] - momCol)
        # 求两级最小差和最大差
        minMin = sonCol.min()
        maxMax = sonCol.max()
        # 计算关联系数矩阵
        cors = (minMin + self.p * maxMax) / (sonCol + self.p * maxMax)
        # 求平均综合关联度
        meanCors = cors.mean(axis=0)
        self.result = {'cors': {'value': cors, 'desc': '关联系数矩阵'}, 'meanCors': {'value': meanCors, 'desc': '平均综合关联系数'}}


if __name__ == "__main__":
    # # 路径目录
    # curDir = os.path.dirname(os.path.abspath(__file__))  # 当前目录
    # baseDir = os.path.dirname(curDir)  # 根目录
    # staticDir = os.path.join(baseDir, 'Static')  # 静态文件目录
    # resultDir = os.path.join(baseDir, 'Result')  # 结果文件目录
    # 读数
    data = [
        [1, 1.1, 2, 2.25, 3, 4],
        [1, 1.166, 1.834, 2, 2.314, 3],
        [1, 1.125, 1.075, 1.375, 1.625, 1.75],
        [1, 1, 0.7, 0.8, 0.9, 1.2]
    ]
    data = np.array(data).T
    # 建模
    model = GraModel(data, standard=True)
    print(model.result)

灰色预测

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np


def GM11(x, n):
    '''
    灰色预测
    x:序列,numpy对象
    n:需要往后预测的个数
    '''
    x1 = x.cumsum()  # 一次累加
    z1 = (x1[:len(x1) - 1] + x1[1:]) / 2.0  # 紧邻均值
    z1 = z1.reshape((len(z1), 1))
    B = np.append(-z1, np.ones_like(z1), axis=1)
    Y = x[1:].reshape((len(x) - 1, 1))
    # a为发展系数 b为灰色作用量
    [[a], [b]] = np.dot(np.dot(np.linalg.inv(np.dot(B.T, B)), B.T), Y)  # 计算参数
    result = (x[0] - b / a) * np.exp(-a * (n - 1)) - (x[0] - b / a) * np.exp(-a * (n - 2))
    S1_2 = x.var()  # 原序列方差
    e = list()  # 残差序列
    for index in range(1, x.shape[0] + 1):
        predict = (x[0] - b / a) * np.exp(-a * (index - 1)) - (x[0] - b / a) * np.exp(-a * (index - 2))
        e.append(x[index - 1] - predict)
    S2_2 = np.array(e).var()  # 残差方差
    C = S2_2 / S1_2  # 后验差比
    if C <= 0.35:
        assess = '后验差比<=0.35,模型精度等级为好'
    elif C <= 0.5:
        assess = '后验差比<=0.5,模型精度等级为合格'
    elif C <= 0.65:
        assess = '后验差比<=0.65,模型精度等级为勉强'
    else:
        assess = '后验差比>0.65,模型精度等级为不合格'
    # 预测数据
    predict = list()
    for index in range(x.shape[0] + 1, x.shape[0] + n + 1):
        predict.append((x[0] - b / a) * np.exp(-a * (index - 1)) - (x[0] - b / a) * np.exp(-a * (index - 2)))
    predict = np.array(predict)
    return {
        'a': {'value': a, 'desc': '发展系数'},
        'b': {'value': b, 'desc': '灰色作用量'},
        'predict': {'value': result, 'desc': '第%d个预测值' % n},
        'C': {'value': C, 'desc': assess},
        'predict': {'value': predict, 'desc': '往后预测%d个的序列' % (n)},
    }


if __name__ == "__main__":
    data = np.array([1.2, 2.2, 3.1, 4.5, 5.6, 6.7, 7.1, 8.2, 9.6, 10.6, 11, 12.4, 13.5, 14.7, 15.2])
    x = data[0:10]  # 输入数据
    y = data[10:]  # 需要预测的数据
    result = GM11(x, len(y))
    predict = result['predict']['value']
    predict = np.round(predict, 1)
    print('真实值:', y)
    print('预测值:', predict)
    print(result)

猜你喜欢

转载自blog.csdn.net/weixin_35757704/article/details/108401798
今日推荐