假设我有一个信号: [1,1,1,1,1,3,3,2,2,2,2,4,1,2,4,2,1,1,1]
1、求信号的均值(可以先归一化)
avg = 1.8947
2、计算均方差
(1-1.8947)平方
(1-1.8947)平方
(1-1.8947)平方
(1-1.8947)平方
(1-1.8947)平方
(3-1.8947)平方
(3-1.8947)平方
(2-1.8947)平方
(2-1.8947)平方
(2-1.8947)平方
(2-1.8947)平方
(4-1.8947)平方
(1-1.8947)平方
(2-1.8947)平方
(4-1.8947)平方
(2-1.8947)平方
(1-1.847)平方
(1-1.8947)平方
(1-1.8947)平方
其结果为:
各点与均值的偏差: ['-0.895', '-0.895', '-0.895', '-0.895', '-0.895', '1.105', '1.105', '0.105', '0.105', '0.105', '0.105', '2.105', '-0.895', '0.105', '2.105', '0.105', '-0.895', '-0.895', '-0.895'] 分母 = Σ(x[i]-μ)² = 20.8421
3、计算延迟k=1的协方差
i= 0: (1-1.895)×(1-1.895) = -0.895×-0.895 = 0.801 i= 1: (1-1.895)×(1-1.895) = -0.895×-0.895 = 0.801 i= 2: (1-1.895)×(1-1.895) = -0.895×-0.895 = 0.801 i= 3: (1-1.895)×(3-1.895) = -0.895×1.105 = -0.989 i= 4: (3-1.895)×(3-1.895) = 1.105×1.105 = 1.221 i= 5: (3-1.895)×(2-1.895) = 1.105×0.105 = 0.116 i= 6: (2-1.895)×(2-1.895) = 0.105×0.105 = 0.011 i= 7: (2-1.895)×(2-1.895) = 0.105×0.105 = 0.011 i= 8: (2-1.895)×(2-1.895) = 0.105×0.105 = 0.011 i= 9: (2-1.895)×(4-1.895) = 0.105×2.105 = 0.221 i=10: (4-1.895)×(1-1.895) = 2.105×-0.895 = -1.884 i=11: (1-1.895)×(2-1.895) = -0.895×0.105 = -0.094 i=12: (2-1.895)×(4-1.895) = 0.105×2.105 = 0.221 i=13: (4-1.895)×(2-1.895) = 2.105×0.105 = 0.221 i=14: (2-1.895)×(1-1.895) = 0.105×-0.895 = -0.094 i=15: (1-1.895)×(1-1.895) = -0.895×-0.895 = 0.801 i=16: (1-1.895)×(1-1.895) = -0.895×-0.895 = 0.801 i=17: (1-1.895)×(1-1.895) = -0.895×-0.895 = 0.801 分子 = Σ(x[i]-μ)(x[i+1]-μ) = 15.0263
4、最终计算自相关的值
延迟1自相关 R[1] = 分子/分母 = 15.0263 / 20.8421 = 0.721
直观理解
这个0.721的值意味着:
当延迟为1时,信号与其自身有72.1%的相似性
这很高,说明相邻数据点之间有很强的相关性
在信号A中,你经常看到
1,1、2,2、3,3这样的连续相同值,这导致了高自相关
JAVA编程实现:
package model.MyTools;
import testHtt.SystemTools;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class TestCorrecation {
/**
* PPG信号检测方法
* 主要通过自相关函数来判别是否可以对同一个信号进行周期的判断
* author:huitao
* time:2025-11-13
* @param single
* @return
*/
//自相关函数的编程(true表示高度相关,false表示不相关)
public static boolean CorrelationTools(List<Double> single){
double lat=0;
//取平均值
double avg= SystemTools.getAvagetValue(single);
//求差值
List<Double> offsetList= new ArrayList<>();
double offsetResult=0;
for(int i=0;i<single.size();i++){
double offset=single.get(i)-avg;
offsetList.add(offset);
offsetResult += offset*offset; //计算平方
}
offsetResult = offsetResult/single.size();//0位置的相关系数
String formattedNumber = String.format("%.1f", offsetResult);
System.out.print(formattedNumber+"\n");
//计算延迟1的相关
//打点器1
List<Double> nList=getNListValue(single,20);
double point1=0;//获取位置1的点的关系
for(int j=0;j<single.size();j++){
double x1=single.get(j);
double x2=nList.get(j);
double NValue=(x1-avg)*(x2-avg);
point1 += NValue;
}
point1 = point1/single.size();
System.out.print(point1+"\n");
//获取最终自相关系数的关系
double ResultCorrelation=point1/offsetResult;
String formattedNumber1 = String.format("%.1f", ResultCorrelation);
System.out.print(formattedNumber1+"\n");
boolean flag=false;
if(ResultCorrelation>=0.3){
flag=true;
}
return flag;
}
//获取具体位置的对比关系
public static List<Double> getNListValue(List<Double> llopp,int index){
List<Double> nList1=new ArrayList();
List<Double> nList2=new ArrayList();
List<Double> result=new ArrayList();
for(int k=0;k<llopp.size();k++){
if(k>index){
nList2.add(llopp.get(k));//开始
}else{
nList1.add(llopp.get(k));//结束
}
}
result.addAll(nList2);
result.addAll(nList1);
return result;
}
//通过文件读取数据
private static List<Double> readFile(String path) {
List<Double> ll=new ArrayList<>();
String line="";
try
{
BufferedReader in=new BufferedReader(new FileReader(path));
while ((line=in.readLine()) != null)
{
//表示字符串长度不受限制
// String[] str=line.split(" ",-1);
//先把外面的替换掉
String c = line.replaceAll("\r|\n", "");
String[] str=c.split(" ");
for(int i=0;i<str.length;i++){
if (i % 5 == 0 || i % 5 == 1 || i % 5 == 2) {
double dat = Double.parseDouble(str[i]);
// System.out.print(dat+"\n");
ll.add(dat);
}
}
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.print(ll.size());
return ll;
}
public static void main(String[] args){
String path="C:\\Users\\seer\\Desktop\\王总错误数据\\bbbbb.txt";
// String path="C:\\Users\\seer\\Desktop\\王总错误数据\\2025-08-06 103859\\a7c9bff53f2e4a70af7a9f641552507a_1754447849073-35.txt";
// String path="C:\\Users\\seer\\Desktop\\测量无效\\vlide\\error2.txt";
List<Double> lp=readFile(path);
boolean fg=CorrelationTools(lp);
System.out.print(fg);
}
}