123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- //
- // Created by Austin on 2023/10/10.
- //
- #include "EntropyWeights.h"
- #include <QDebug>
- #include <numeric>
- #include <cmath>
- /**
- QVector<QVector<double>> 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<double> weights;
- QVector<double> score;
- ew.compute(weights, score);
- qDebug() << score;
- qDebug() << weights;
- */
- EntropyWeights::EntropyWeights(const EntropyMat &mat, const QVector<bool> &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<double> &weights, QVector<double> &score)
- {
- // 计算第j个指标下,第i个样本占该指标的比重p
- EntropyMat pMat;
- for (int i = 0; i < mat_.count(); i++) {
- pMat.append(QVector<double>(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<double> e(mat_.count(), 0);
- for (int i = 0; i < mat_.count(); i++) {
- // QVector<double> 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<double> 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<double> &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<double> &weights, QVector<double> &score)
- {
- normalization();
- // qDebug() << mat_;
- getWeights(weights, score);
- // qDebug() << "mat_" << mat_;
- }
|