// // Created by Austin on 2023/10/10. // #include "EntropyWeights.h" #include #include #include /** QVector> pdata = { { 4.1, 3.9, 5.9, 4.9, 4, 6.1, 8.2, 6.5, 7.5, 6.8, 7.4, 5.7, 2.4, 2.2, 1.9, 1.8, 15.9, 18.9, 18.8, 16.8 }, { 0.04, 0.08, 0.07, 0.23, 0.14, 0.23, 0.21, 0.13, 0.16, 0.04, 0.05, 0.08, 0.14, 0.24, 0.11, 0.06, 0.2, 0.09, 0.12, 0.27 }, { 0.19, 0.38, 0.23, 1.03, 0.57, 1.19, 0.88, 0.8, 1.28, 0.17, 0.33, 0.6, 0.23, 0.35, 0.3, 0.28, 1.05, 0.82, 0.8, 1.74 }, { 0.01, 0.18, 0.04, 0.3, 0.11, 0.47, 0.2, 0.26, 0.88, 0.02, 0.06, 0.47, 0.04, 0.06, 0.1, 0.1, 0.21, 0.34, 0.39, 1.51 }, { 0.36, 0.19, 0.36, 1.4, 1.12, 0.93, 0.97, 0.52, 0.8, 0.24, 0.39, 0.46, 0.94, 1.78, 0.5, 0.29, 1.84, 0.58, 0.76, 1.78 }, { 0.05, 0.04, 0.07, 0.09, 0.05, 0.07, 0.1, 0.09, 0.12, 0.11, 0.1, 0.08, 0.02, 0.02, 0.04, 0.03, 0.12, 0.36, 0.26, 0.32 } }; EntropyWeights ew(pdata); QVector weights; QVector score; ew.compute(weights, score); qDebug() << score; qDebug() << weights; */ EntropyWeights::EntropyWeights(const EntropyMat &mat, const QVector &direction) : ymin_(0.002), ymax_(0.996), mat_(mat), direction_(direction) { index_num_ = mat_.count(); if (index_num_ == 0) { sample_num_ = 0; } else { sample_num_ = mat_.at(0).count(); } } void EntropyWeights::setYMin(double ymin) { if (ymin < 0.002) { ymin_ = 0.002; } else if (ymin > ymax_) { return; } ymin_ = ymin; } void EntropyWeights::setYMax(double ymax) { if (ymax > 0.996) { ymax_ = 0.996; } else if (ymax < ymin_) { return; } ymax_ = ymax; } void EntropyWeights::getWeights(QVector &weights, QVector &score) { // 计算第j个指标下,第i个样本占该指标的比重p EntropyMat pMat; for (int i = 0; i < mat_.count(); i++) { pMat.append(QVector(mat_.at(i).count(), 0)); double sum = std::accumulate(mat_.at(i).begin(), mat_.at(i).end(), 0.0); for (int j = 0; j < mat_.at(i).count(); j++) { pMat[i][j] = mat_[i][j] / sum; } } double k = 1 / std::log(sample_num_); // 计算第j个指标熵值 QVector e(mat_.count(), 0); for (int i = 0; i < mat_.count(); i++) { // QVector f(mat_.at(i).count(), 0.0); double fSum = 0; for (int j = 0; j < mat_.at(i).count(); j++) { fSum += pMat[i][j] * std::log(pMat[i][j]); } e[i] = -k * fSum; } // qDebug() << e; // 计算信息熵冗余度 QVector d(mat_.count(), 0); for (int i = 0; i < e.count(); i++) { d[i] = 1 - e[i]; } // 求权值 double dSum = std::accumulate(d.begin(), d.end(), 0.0); for (auto v : d) { weights.append(v / dSum); } for (int i = 0; i < sample_num_; ++i) { double s = 0; for (int j = 0; j < index_num_; j++) { s += pMat[j][i] * weights[j]; } score.append(s * 100); } } /** * 实现正向或负向指标归一化,返回归一化后的数据矩阵 */ void EntropyWeights::normalization() { for (int i = 0; i < mat_.count(); i++) { double minValue = 0; double maxValue = 0; getMinMax(mat_.at(i), minValue, maxValue); bool dir = true; if (!direction_.isEmpty()) { dir = direction_.at(i); } if (dir) { for (int j = 0; j < mat_.at(i).count(); j++) { mat_[i][j] = (ymax_ - ymin_) * (mat_.at(i).at(j) - minValue) / (maxValue - minValue) + ymin_; } } else { for (int j = 0; j < mat_.at(i).count(); j++) { mat_[i][j] = (ymax_ - ymin_) * (maxValue - mat_.at(i).at(j)) / (maxValue - minValue) + ymin_; } } } } void EntropyWeights::getMinMax(const QVector &in, double &min, double &max) { if (in.count() > 0) { min = max = in.at(0); for (int i = 1; i < in.count(); i++) { if (in.at(i) < min) { min = in.at(i); } else if (in.at(i) > max) { max = in.at(i); } } } } void EntropyWeights::compute(QVector &weights, QVector &score) { normalization(); // qDebug() << mat_; getWeights(weights, score); // qDebug() << "mat_" << mat_; }