【0】README
0.1)本文旨在讲解 哈儿小波变换(分解和重构)进行数据的降维和升维;
【timestamp: 1703281610】
时隔几个月再来review 哈儿小波变换算法的具体思路:
1)分解降维:首先对所有item进行分解降维,求相邻维度的两个元素的和均值和差均值,如 array[0] 和 array[1]为一组,array[2]和array[3]为一组;分别存储在 array[i] array[i+span], 其中span=该当前分辨率下的 分辨率长度,如当前分辨率为resolution, 则 length=2^resolution;
2)item重构升维:当前分辨率为curResolution,则
int span = (int) pow(2, curResolution);
for (int i = 0; i < span; i++) {
temp[2*i] = rawitem[i] + rawitem[i+span];
temp[2*i+1] = rawitem[i] - rawitem[i+span];
}
因为 rawitem[i] 和 rawitem[i+span]是 降维时的和均值和差均值;
3)质心重构升维: 只需要将较低分辨率下的质心扩展一倍,如
if(ClusterData.resolutionLength < ClusterData.dimension) {
for (int j = ClusterData.resolutionLength-1; j >= 0 ; j--) {
ClusterData.centroid[i][2*j] = ClusterData.centroid[i][j];
ClusterData.centroid[i][2*j+1] = ClusterData.centroid[i][j];
}
}
【1】intro to 哈儿小波
1.1)定义:哈尔小波变换分为哈尔小波分解和重构。本文利用哈尔小波分解和哈尔小波重构分别对社交网络中的时间序列进行降维和升维操作,而分解降维和重构升维互为逆过程,这里以哈尔小波分解降维步骤为例进行说明。
1.2)哈尔小波分解(重构是其逆过程):可以被看作是一系列对离散时间函数的均值和差操作。本文计算离散函数f(t),即时间序列元素值的每两个相邻值间的均值和差。找出离散函数f(t)={9, 7, 3, 5}的哈尔小波分解过程如下表所示:
分辨率 级别 | 分辨率 (维度) | 均值 | 差值 | 哈尔小波 分解系数 | 降维后的 时序 | 全分辨率下的时序 |
2 | 4 | {9,7,3,5} |
| {9,7,3,5} |
| {9,7,3,5} |
1 | 2 | {8,4} | {1,-1} | {8,4,1,-1} | {8,4} | {8,8,4,4} |
0 | 1 | {6} | {2} | {6,2,1,-1} | {6} | {6,6,6,6} |
A1)intro to 分辨率:哈儿小波分解和重构常应用于图像的降维和升维,这里的分辨率,你与可以理解为是图像的分辨率,分辨率越低,图像质量越不清晰,分辨率越高图片质量越清晰(数据显示更加丰富);(干货——我们看到的图片为什么不清晰)
A2)上表中最后一列(全分辨率下的时序):我们看到数据由 [9 7 3 5] 到 [8 8 4 4] 再到 [6 6 6 6],显然在一个图像的某个区域内,分辨率越低,数据越不丰富,变化越不明显,这也是为什么低分辨率下数据模糊的一个原因(因为低分辨率下,数据经过降维处理了);
【2】将上述哈尔小波分解过程用倒置二叉树表示如下:
【3】看个荔枝
对上图的分析(Analysis):
A1)以上数据[2, 5, 8, 9, 7, 4, -1, 1]在不同分辨率下经过哈儿小波变换得到的数据如下:
分辨率3:它本身;
分辨率2:3.5, 8.5, 5.5, 0, -1.5, -0.5, 1.5, -1;
分辨率1:6, 2.75, -2.5, 2.75, -1.5, -0.5, 1.5, -1;
分辨率0:4.375, 1.625, -2.5, 2.75, -1.5, -0.5, 1.5, -1;
A2)哈儿小波变换分为哈儿小波分解和哈儿小波重构,且我们可以指定最低级分辨率(并不一定是0);
【4】将哈儿小波变换应用到Kmeans聚类算法(干货——目的是降低聚类时间复杂度)
1)Kmeans聚类进行前:先对数据进行哈儿小波分解以降维到0分辨率(或你自己指定)(干货——聚类开始前,我们数据的分辨率是0,而维度是1,即2^0=1);
2)Kmeans聚类过程中:聚类是一个迭代的过程,每轮迭代,我们都对数据进行哈儿小波重构进行升维(以降低聚类时间复杂度);
如第1轮聚类后,我们将数据升维到分辨率1下;第2轮迭代后,将数据升维到分辨率2下,以此类推......;当达到全分辨率下时,我们不再进行哈儿小波变换,但可以继续聚类,直到满足聚类结束标志的条件为止;
【5】哈儿小波分解和重构源代码实现
5.1)哈儿小波分解和重构的源代码
public class HaarTransform{
public static int maxResolution;
/**
* executing haar reconstruction transform towards given array
* @param rawitem raw array
* @param curResolution current resolution
*/
public static void haarReconstruct(double[] rawitem, int curResolution) {
double[] temp = new double[rawitem.length];
System.arraycopy(rawitem, 0, temp, 0, temp.length);
int span = (int) pow(2, curResolution);
for (int i = 0; i < span; i++) {
temp[2*i] = rawitem[i] + rawitem[i+span];
temp[2*i+1] = rawitem[i] - rawitem[i+span];
}
System.arraycopy(temp, 0, rawitem, 0, temp.length);
}
/**
* @param rawitem is a array
* @param leastResolution is the least resolution allowed be zero.
* @param maxResolution is equals to log(full dimension)
* @return
*/
public static double[] haarDecompose(double[] rawitem, int leastResolution) {
double[] temp = new double[rawitem.length];
int resolutionLength = rawitem.length;
int maxResolution = HaarTransform.maxResolution;
// if rawitem.length=8, maxResolution = 3;
// you know least resolution equals to 0.
for (int i = maxResolution; i > leastResolution; i--) {
System.out.println("第"+i+"级分辨率下");
AlgTools.printOneDimArray(rawitem);
for (int j = 0; j < resolutionLength / 2; j++) {
temp[j] = (rawitem[2*j] + rawitem[2*j+1]) / 2;
temp[resolutionLength/2+j] = (rawitem[2*j] - rawitem[2*j+1]) / 2;
}
resolutionLength /= 2;
System.arraycopy(temp, 0, rawitem, 0, temp.length);
}
return temp;
}
}
5.2)哈儿小波分解和重构的测试用例
public class HaarTransformTest {
public static void main(String[] args) {
double[] data = {2, 5, 8, 9, 7, 4, -1, 1};
int resolutionNum = (int) (log(data.length) / log(2));
System.out.println("分辨率总级别个数为: " + resolutionNum);
HaarTransform.maxResolution = resolutionNum;
int leastResolution = 0;
HaarTransform.haarDecompose(data, leastResolution);
System.out.println("最低级分辨率"+leastResolution+"下");
AlgTools.printOneDimArray(data);
// 哈儿小波分解over.
for (int i = leastResolution; i < resolutionNum; i++) {
HaarTransform.haarReconstruct(data, i);
System.out.println("第"+ (i+1) + "级分辨率下");
AlgTools.printOneDimArray(data);
}// 哈儿小波重构over.
}
}
对以上代码的分析(Analysis):
A1)因为总共维度是8,所以最大分辨率==log8=3;
A2)上述哈儿小波分解过程中对应的变量变化如下(为了便于更加理解分解过程):
循环次数 round | 分辨率级别 i | 分辨率级别的对应维度 resolutionLength | j(max) | 下一分辨率级别 的维度sum |
1 | 3 | 8 | 3(0~3) | 4 |
2 | 2 | 4 | 1(0~1) | 2 |
3 | 1 | 2 | 0(0~0) | 1 |
4 | 0 | 1 |
|
|
分辨率总级别个数为: 3
第3级分辨率下
2.000 5.000 8.000 9.000 7.000 4.000 -1.000 1.000
第2级分辨率下
3.500 8.500 5.500 0.000 -1.500 -0.500 1.500 -1.000
第1级分辨率下
6.000 2.750 -2.500 2.750 -1.500 -0.500 1.500 -1.000
最低级分辨率0下
4.375 1.625 -2.500 2.750 -1.500 -0.500 1.500 -1.000
第1级分辨率下
6.000 2.750 -2.500 2.750 -1.500 -0.500 1.500 -1.000
第2级分辨率下
3.500 8.500 5.500 0.000 -1.500 -0.500 1.500 -1.000
第3级分辨率下
2.000 5.000 8.000 9.000 7.000 4.000 -1.000 1.000