// utils/ppmcc.go
package utils
import (
"errors"
"math"
)
var LengthError = errors.New("请检查变量X与变量Y样本大小是否相等!")
type PPMCCUtil interface {
// 求均值
getAverageValue()
// 求协方差
getCovariance() float64
// 求标准差
getStandardDeviation() float64
// 求相关系数
getPPMCC() (float64, error)
}
type VariableArray struct {
// 样本数据 X
X []float64
// 样本数据 Y
Y []float64
// 样本大小
Samplesize int
}
// 求均值
func (v *VariableArray) getAverageValue() {
var xSum float64 = 0
var ySum float64 = 0
for i := 0; i < v.Samplesize; i++ {
xSum = xSum + v.X[i]
ySum = ySum + v.Y[i]
}
// 新增一位用于保存均值
v.X = append(v.X, xSum/float64(v.Samplesize))
v.Y = append(v.Y, ySum/float64(v.Samplesize))
}
// 求协方差
func (v *VariableArray) getCovariance() float64 {
var res float64 = 0
for i := 0; i < v.Samplesize; i++ {
res = res + (v.X[i]-v.X[v.Samplesize])*(v.Y[i]-v.Y[v.Samplesize])
}
return res
}
// 求标准差
func (v *VariableArray) getStandardDeviation() float64 {
var xRes float64 = 0
var yRes float64 = 0
for i := 0; i < v.Samplesize; i++ {
xRes = xRes + (v.X[i]-v.X[v.Samplesize])*(v.X[i]-v.X[v.Samplesize])
yRes = yRes + (v.Y[i]-v.Y[v.Samplesize])*(v.Y[i]-v.Y[v.Samplesize])
}
// math.Sqrt() 开根号函数
var res float64 = math.Sqrt(xRes) * math.Sqrt(yRes)
return res
}
// 求相关系数
func (v *VariableArray) getPPMCC() (float64, error) {
if len(v.X) != len(v.Y) {
return 0, LengthError
}
v.getAverageValue()
return v.getCovariance() / v.getStandardDeviation(), nil
}
func Corrcoef(x []float64, y []float64) (float64, error) {
var ppmccUtil PPMCCUtil = &VariableArray{
X: x,
Y: y,
Samplesize: len(x),
}
ppmcc, err := ppmccUtil.getPPMCC()
if err != nil {
return 0, nil
}
return ppmcc, nil
}
测试:
package main
import (
"fmt"
. "ppmcc/utils"
)
func main() {
x := []float64{1, 2, 3, 4, 5, 6}
y := []float64{1, 20, 3, 40, 5, 60}
res, err := Corrcoef(x, y)
if err != nil {
fmt.Println(err)
}
fmt.Println(res)
}
运行结果:
对比 numpy 库: