mirror of
https://github.com/sjwhitworth/golearn.git
synced 2025-04-26 13:49:14 +08:00
Add metric interface, add polynomial kernel.
This commit is contained in:
parent
0eaf944764
commit
b473ff6881
@ -4,23 +4,27 @@ import (
|
||||
"fmt"
|
||||
|
||||
pariwiseMetrics "github.com/sjwhitworth/golearn/metrics/pairwise"
|
||||
"github.com/sjwhitworth/golearn/utilities"
|
||||
mat "github.com/skelterjohn/go.matrix"
|
||||
)
|
||||
|
||||
func main() {
|
||||
randArray := utilities.RandomArray(3, 7)
|
||||
vectorX := mat.MakeDenseMatrix(randArray, 1, 3)
|
||||
randArray = utilities.RandomArray(3, 7)
|
||||
vectorY := mat.MakeDenseMatrix(randArray, 1, 3)
|
||||
vectorX := mat.MakeDenseMatrix([]float64{1, 2, 3}, 3, 1)
|
||||
vectorY := mat.MakeDenseMatrix([]float64{3, 4, 5}, 3, 1)
|
||||
|
||||
distance, err := pariwiseMetrics.Euclidean(vectorX, vectorY)
|
||||
euclidean := pariwiseMetrics.NewEuclidean()
|
||||
polyKernel := pariwiseMetrics.NewPolyKernel(3)
|
||||
|
||||
euclideanDistance, err := euclidean.Distance(vectorX, vectorY)
|
||||
polyKernelDistance, err := polyKernel.Distance(vectorX, vectorY)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Euclidean distance of " + vectorX.String() + " and " + vectorY.String() + " is: ")
|
||||
fmt.Println(distance)
|
||||
fmt.Println("Vector X:")
|
||||
fmt.Println(vectorX.String())
|
||||
fmt.Println("Vector Y: ")
|
||||
fmt.Println(vectorY.String())
|
||||
fmt.Println("Euclidean : ", euclideanDistance)
|
||||
fmt.Println("PolyKernel(degree 3): ", polyKernelDistance)
|
||||
}
|
||||
|
@ -1,30 +1,32 @@
|
||||
package pairwise
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"math"
|
||||
|
||||
mat "github.com/skelterjohn/go.matrix"
|
||||
)
|
||||
|
||||
// We may need to create Metrics / Vector interface for this
|
||||
func Euclidean(vectorX *mat.DenseMatrix, vectorY *mat.DenseMatrix) (float64, error) {
|
||||
var sum float64
|
||||
type Euclidean struct{}
|
||||
|
||||
difference, err := vectorY.MinusDense(vectorX)
|
||||
|
||||
flat := difference.Array()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return -1, err
|
||||
}
|
||||
|
||||
for _, i := range flat {
|
||||
squared := math.Pow(i, 2)
|
||||
sum += squared
|
||||
}
|
||||
|
||||
distance := math.Sqrt(sum)
|
||||
return distance, nil
|
||||
func NewEuclidean() *Euclidean {
|
||||
return &Euclidean{}
|
||||
}
|
||||
|
||||
func (self *Euclidean) InnerProduct(vectorX *mat.DenseMatrix, vectorY *mat.DenseMatrix) (float64, error) {
|
||||
if !CheckDimMatch(vectorX, vectorY) {
|
||||
return 0, errors.New("Dimension mismatch")
|
||||
}
|
||||
|
||||
result := mat.Product(mat.Transpose(vectorX), vectorY).Get(0, 0)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// We may need to create Metrics / Vector interface for this
|
||||
func (self *Euclidean) Distance(vectorX *mat.DenseMatrix, vectorY *mat.DenseMatrix) (float64, error) {
|
||||
difference, err := vectorY.MinusDense(vectorX)
|
||||
result, err := self.InnerProduct(difference, difference)
|
||||
|
||||
return math.Sqrt(result), err
|
||||
}
|
||||
|
20
metrics/pairwise/pairwise.go
Normal file
20
metrics/pairwise/pairwise.go
Normal file
@ -0,0 +1,20 @@
|
||||
package pairwise
|
||||
|
||||
import (
|
||||
mat "github.com/skelterjohn/go.matrix"
|
||||
)
|
||||
|
||||
type Metric interface {
|
||||
InnerProduct(vectorX *mat.DenseMatrix, vectorY *mat.DenseMatrix)
|
||||
Distance(vectorX *mat.DenseMatrix, vectorY *mat.DenseMatrix)
|
||||
}
|
||||
|
||||
func CheckDimMatch(vectorX *mat.DenseMatrix, vectorY *mat.DenseMatrix) bool {
|
||||
if vectorX.Cols() != 1 ||
|
||||
vectorY.Cols() != 1 ||
|
||||
vectorX.Rows() != vectorY.Rows() {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
34
metrics/pairwise/poly_kernel.go
Normal file
34
metrics/pairwise/poly_kernel.go
Normal file
@ -0,0 +1,34 @@
|
||||
package pairwise
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
|
||||
mat "github.com/skelterjohn/go.matrix"
|
||||
)
|
||||
|
||||
type PolyKernel struct {
|
||||
degree int
|
||||
}
|
||||
|
||||
func NewPolyKernel(degree int) *PolyKernel {
|
||||
return &PolyKernel{degree: degree}
|
||||
}
|
||||
|
||||
func (self *PolyKernel) InnerProduct(vectorX *mat.DenseMatrix, vectorY *mat.DenseMatrix) (float64, error) {
|
||||
if !CheckDimMatch(vectorX, vectorY) {
|
||||
return 0, errors.New("Dimension mismatch")
|
||||
}
|
||||
|
||||
result := mat.Product(mat.Transpose(vectorX), vectorY).Get(0, 0)
|
||||
result = math.Pow(result+1, float64(self.degree))
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (self *PolyKernel) Distance(vectorX *mat.DenseMatrix, vectorY *mat.DenseMatrix) (float64, error) {
|
||||
difference, err := vectorY.MinusDense(vectorX)
|
||||
result, err := self.InnerProduct(difference, difference)
|
||||
|
||||
return math.Sqrt(result), err
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user