算法实现简述
我使用C++的armadillo矩阵运算库实现了灰度关联分析,可以进行权重分析。
类的结构
/*灰度关联分析:判断一组向量与一个向量的关联程度
核心思想:归一化、关联度越大,其曼哈顿距离越小
*/
class GRA
{
public:
GRA(double coeff_ = 0.5)
{
coeff = coeff_;
}
GRA& loadData(mat& data);
GRA& loadData(mat& data, vec& mainData);
GRA& setCoeff(double coeff_);
GRA& caculate(std::string method = "firstNorm");
rowvec& coeffVec();
private:
double coeff;//在[0,1]
rowvec final_coeff;//最终的系数
mat dat;
};
类的实现
GRA & GRA::loadData(mat & data)
{
dat = data;
return *this;
}
GRA & GRA::loadData(mat & data, vec & mainData)
{
dat.zeros(data.n_rows, data.n_cols + 1);
dat.col(0) = mainData;
dat.submat(0, 1, data.n_rows - 1, data.n_cols) = data;
return *this;
}
GRA & GRA::setCoeff(double coeff_)
{
coeff = coeff_;
return *this;
}
GRA & GRA::caculate(std::string method)
{
//初值归一化
if (method == "firstNorm")
{
for (int i{ 1 }; i < dat.n_rows; ++i)
{
dat.row(i) = dat.row(i) / dat.row(0);
}
}
//平均值归一化
else if (method == "avgNorm")
{
dat = (dat - mean(dat)) / sqrt(cov(dat));
}
//不归一化
else if (method == "none")
{
}
//抛出异常
else
{
throw Exception("GRA Caculate method error, check parameter \"none\" \"avgNorm\" \"firstNorm\".");
}
//求关联系数
mat tmp{dat.n_rows,dat.n_cols};
for (int i{ 0 }; i < dat.n_cols; ++i)
{
tmp.col(i) = dat.col(0) - dat.col(i);
}
tmp = abs(tmp);
#ifdef _DEBUG
cout << dat << endl;
#endif
tmp = (min(min(tmp)) + coeff * max(max(tmp))) / (tmp + coeff*max(max(tmp)));
#ifdef _DEBUG
cout << tmp << endl;
#endif
//求关联度
final_coeff = mean(tmp);
return *this;
}
rowvec & GRA::coeffVec()
{
return final_coeff;
}