葡萄酒分级是这次MCM的一问,刚好模糊数学结业作业是运用模糊数学东西,模式识别,模糊决策,聚类分析什么的写一篇应用报告或论文,撞枪口上了。
先解释一些聚类分析的含义,对于一个集合中包含若干元素,他们之间存在着模糊关系(就是不是绝对联系也不是绝对不联系的情况,联系度在[0,1]之间),于是,我们可以通过建立相关矩阵,对其进行截取找到一个划分,可以把集合分为几个内部关联很大的类。
当然,这道题我用的只是基于模糊矩阵的聚类算法,感觉运用模糊C均值划分会更好一些,可惜我不是弄MCM,我只需要交片paper糊弄过老师就OK了,模糊C均值和L模型个人感觉是解这问比较好的方法,不过理论相当复杂,而且实现部分设计积分偏导.....所以,大家量力而行吧,如果想学习的话建议参考模糊集合论及应用。
言归正传
首先我们对28种白葡萄酒的葡萄的理化指标经行聚类分析,因为单纯从葡萄的理化指标很难看出酒的好坏,但能找到指标相近的几种葡萄作为一类。
所以,先对数据经行标准化
我用的是平移极差变化
这样就能消除了量纲的限制,控制在[0,1]之间。
之后对得到的28组数据向量经行建立模糊相似矩阵,矩阵的元素Rij表示第i个元素和第j个元素的关系度,而建立的方法有很多种,这里采用的是算数均值最小法,主要是方便运算,但从数据结果来看出现了不小的误差,建议改用距离法和夹角余弦法。
算数均值最小法:
距离法:
夹角余弦法:
当然,如果你感觉你对数字够敏感,分析角度够犀利,可以主观自己构造。
得到模糊矩阵后需要对矩阵求解传递闭包,因为不具有传递性的矩阵不一定能截出正常分类,而求解一个矩阵的传递闭包方法就是对矩阵自乘,得到新矩阵如果和旧矩阵一样说明已经是传递闭包,如果不是继续对新矩阵自乘。
得到传递闭包后,数据如下:
1.000000 0.795914 0.758670 0.758670 0.758670 0.795914 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.682214 0.758670 0.758670 0.758670 0.776950 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.795914 1.000000 0.758670 0.758670 0.758670 0.841503 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.682214 0.758670 0.758670 0.758670 0.776950 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 1.000000 0.787479 0.782909 0.758670 0.787922 0.771737 0.787479 0.796723 0.765201 0.807563 0.787922 0.776075 0.807563 0.782909 0.682214 0.787922 0.787479 0.807563 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.787479 1.000000 0.782909 0.758670 0.787479 0.771737 0.810414 0.787479 0.765201 0.787479 0.787479 0.776075 0.787479 0.782909 0.682214 0.787479 0.803698 0.787479 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.782909 0.782909 1.000000 0.758670 0.782909 0.771737 0.782909 0.782909 0.765201 0.782909 0.782909 0.776075 0.782909 0.790156 0.682214 0.782909 0.782909 0.782909 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.795914 0.841503 0.758670 0.758670 0.758670 1.000000 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.682214 0.758670 0.758670 0.758670 0.776950 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.787922 0.787479 0.782909 0.758670 1.000000 0.771737 0.787479 0.787922 0.765201 0.787922 0.807559 0.776075 0.787922 0.782909 0.682214 0.807559 0.787479 0.787922 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.771737 0.771737 0.771737 0.758670 0.771737 1.000000 0.771737 0.771737 0.765201 0.771737 0.771737 0.771737 0.771737 0.771737 0.682214 0.771737 0.771737 0.771737 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.787479 0.810414 0.782909 0.758670 0.787479 0.771737 1.000000 0.787479 0.765201 0.787479 0.787479 0.776075 0.787479 0.782909 0.682214 0.787479 0.803698 0.787479 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.796723 0.787479 0.782909 0.758670 0.787922 0.771737 0.787479 1.000000 0.765201 0.796723 0.787922 0.776075 0.796723 0.782909 0.682214 0.787922 0.787479 0.796723 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.765201 0.765201 0.765201 0.758670 0.765201 0.765201 0.765201 0.765201 1.000000 0.765201 0.765201 0.765201 0.765201 0.765201 0.682214 0.765201 0.765201 0.765201 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.807563 0.787479 0.782909 0.758670 0.787922 0.771737 0.787479 0.796723 0.765201 1.000000 0.787922 0.776075 0.866354 0.782909 0.682214 0.787922 0.787479 0.808526 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.787922 0.787479 0.782909 0.758670 0.807559 0.771737 0.787479 0.787922 0.765201 0.787922 1.000000 0.776075 0.787922 0.782909 0.682214 0.875720 0.787479 0.787922 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.776075 0.776075 0.776075 0.758670 0.776075 0.771737 0.776075 0.776075 0.765201 0.776075 0.776075 1.000000 0.776075 0.776075 0.682214 0.776075 0.776075 0.776075 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.807563 0.787479 0.782909 0.758670 0.787922 0.771737 0.787479 0.796723 0.765201 0.866354 0.787922 0.776075 1.000000 0.782909 0.682214 0.787922 0.787479 0.808526 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.782909 0.782909 0.790156 0.758670 0.782909 0.771737 0.782909 0.782909 0.765201 0.782909 0.782909 0.776075 0.782909 1.000000 0.682214 0.782909 0.782909 0.782909 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 1.000000 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.682214 0.673651 0.682214 0.682214
0.758670 0.758670 0.787922 0.787479 0.782909 0.758670 0.807559 0.771737 0.787479 0.787922 0.765201 0.787922 0.875720 0.776075 0.787922 0.782909 0.682214 1.000000 0.787479 0.787922 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.787479 0.803698 0.782909 0.758670 0.787479 0.771737 0.803698 0.787479 0.765201 0.787479 0.787479 0.776075 0.787479 0.782909 0.682214 0.787479 1.000000 0.787479 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.758670 0.758670 0.807563 0.787479 0.782909 0.758670 0.787922 0.771737 0.787479 0.796723 0.765201 0.808526 0.787922 0.776075 0.808526 0.782909 0.682214 0.787922 0.787479 1.000000 0.758670 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.776950 0.776950 0.758670 0.758670 0.758670 0.776950 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.758670 0.682214 0.758670 0.758670 0.758670 1.000000 0.746148 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.746148 0.682214 0.746148 0.746148 0.746148 0.746148 1.000000 0.741932 0.695674 0.739005 0.673651 0.695674 0.744374
0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.741932 0.682214 0.741932 0.741932 0.741932 0.741932 0.741932 1.000000 0.695674 0.739005 0.673651 0.695674 0.741932
0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.682214 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 1.000000 0.695674 0.673651 0.778412 0.695674
0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.682214 0.739005 0.739005 0.739005 0.739005 0.739005 0.739005 0.695674 1.000000 0.673651 0.695674 0.739005
0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 0.673651 1.000000 0.673651 0.673651
0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.682214 0.695674 0.695674 0.695674 0.695674 0.695674 0.695674 0.778412 0.695674 0.673651 1.000000 0.695674
0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.744374 0.682214 0.744374 0.744374 0.744374 0.744374 0.744374 0.741932 0.695674 0.739005 0.673651 0.695674 1.000000
之后对该闭包分析,发现用0.739005去截取,能得到四个类,第一类{24, 27},第二类{17},第三类{26},第四类其他,发现大多数集中在一个类中,说名数据在小关系度下截取分化程度不大,可能是数据故意这样的,或者我的算模糊相似矩阵的做法误差很大。
之后,结合那个评分文件,我一开始只是结合了整体评分,后来发现还有结合质量,算到最后发现不结合质量还真有问题,于是分为四个等级:
第一级:17
第二级:1、2,、3等大类
第三级:26
第四级:24、27。
红酒方法和这差不多,不过我这里只有白酒的和不全的评分数据,所以只能做这么多了。
第四问:证能否用葡萄和葡萄酒的理化指标来评价葡萄酒的质量,个人感觉是能的,不过因为对没有数据分析,所以不确定,具体做做法就是对理化指标和质量两个数据结合分级进行分析,如果存在关系,那么就可以用已知的这几十类酒作为模型建模,对于新加入的样品,在已有模型上寻找最大隶属度即可。
鄙人不怎么用matlab,所以数据处理都是用C++写的。
代码:
这是对数据的处理,生成传递闭包。
#include
#include
#include
using namespace std;
double r[30][100];
double map[30][100];
double R[30][100];
int min(int x, int y)
{
if (x < y)
return x;
return y;
}
int main()
{
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
cin >> r[i][j];
}
}
for (int i = 1; i <= m; ++i)
{
double maxl = 0, minl = 10000;
for (int j = 1; j <= n; ++j)
{
if (maxl < r[j][i]) maxl = r[j][i];
if (minl > r[j][i]) minl = r[j][i];
}
for (int j = 1; j <= n; ++j)
{
map[j][i] = (r[j][i] - minl) / (maxl - minl);
}
}
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
R[i][j] = 0.0;
if (i == j)
R[i][j] = 1;
else
{
double fenzi = 0.0, fenmu = 0.0;
for (int k = 1; k <= m; ++k)
{
fenzi += min(map[i][k], map[j][k]);
fenmu += (map[i][k] + map[j][k]);
}
R[i][j] = fenzi * 2 / fenmu;
}
}
}
double R1[30][100];
int flag = 1;
while (flag)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
double now = 0;
for (int k = 1; k <= n; ++k)
{
now = max(now, min(R[i][k], R[k][j]));
}
R1[i][j] = now;
}
}
flag = 0;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (fabs(R[i][j] - R1[i][j]) > 0.00000000001)
flag = 1, R[i][j] = R1[i][j];
}
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
printf("%6lf ", R[i][j]);
}
cout << endl;
}
return 0;
}
这是对闭包求解,经行分类
#include
#include
#include
#include
using namespace std;
double R[30][100];
double so[100];
int n, m;
int Check(double x)
{
int X[30][100];
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (R[i][j] >= x)
X[i][j] = 1;
else
X[i][j] = 0;
int ans = 0;
int flag[100];
memset(flag, 0, sizeof(flag));
for (int i = 1; i <= n; ++i)
{
if (flag[i] == 0)
{
ans++;
flag[i] = ans;
for (int j = 1; j <= n; ++j)
if (X[i][j] == 1)
flag[j] = ans;
}
}
if (ans == 4)
{
cout << x << endl;
for (int i = 1; i <= ans; ++i)
{
printf("第%d组: ", i);
for (int j = 1; j <= n; ++j)
if (flag[j] == i)
printf("%d:%.1lf ", j, so[j]);
printf("\n");
}
printf("\n");
return 1;
}
return 0;
}
int main()
{
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
cin >> n >> m;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
cin >> R[i][j];
for (int i = 1; i <= n; ++i)
{
int x, y, ma = 0, mi = 100;
double all = 0;
cin >> x;
for (int k = 1; k <= 10; ++k)
{
cin >> y;
all += y;
if (y > ma) ma = y;
if (y < mi) mi = y;
}
all = (all - ma - mi) / 8.0;
so[x] = all;
}
for (int i = 1; i <= n; ++i)
cout << so[i] << endl;
for (int i = 1; i <= n; ++i)
{
for (int j = i + 1; j <= n; ++j)
if (Check(R[i][j]))
return 0;;
}
return 0;
}