1
0
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:
Bert Chang 2014-05-02 20:09:54 +08:00
parent 0eaf944764
commit b473ff6881
4 changed files with 88 additions and 28 deletions

View File

@ -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)
}

View File

@ -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
}

View 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
}
}

View 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
}