mirror of
https://github.com/sjwhitworth/golearn.git
synced 2025-04-28 13:48:56 +08:00
Merge pull request #206 from Sentimentron/gonum
Update gonum to the latest version
This commit is contained in:
commit
623af61265
@ -1,7 +1,9 @@
|
|||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
- 1.7
|
- "1.7"
|
||||||
- 1.8
|
- "1.8"
|
||||||
|
- "1.9"
|
||||||
|
- "1.10"
|
||||||
env:
|
env:
|
||||||
# Temporary workaround for go 1.6
|
# Temporary workaround for go 1.6
|
||||||
- GODEBUG=cgocheck=0
|
- GODEBUG=cgocheck=0
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package base
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Classifier implementations predict categorical class labels.
|
// Classifier implementations predict categorical class labels.
|
||||||
@ -37,7 +37,7 @@ type BaseClassifier struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BaseRegressor struct {
|
type BaseRegressor struct {
|
||||||
Data mat64.Dense
|
Data mat.Dense
|
||||||
Name string
|
Name string
|
||||||
Labels []float64
|
Labels []float64
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package base
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkAllAttributesAreFloat(attrs []Attribute) error {
|
func checkAllAttributesAreFloat(attrs []Attribute) error {
|
||||||
@ -18,8 +18,8 @@ func checkAllAttributesAreFloat(attrs []Attribute) error {
|
|||||||
|
|
||||||
// ConvertRowToMat64 takes a list of Attributes, a FixedDataGrid
|
// ConvertRowToMat64 takes a list of Attributes, a FixedDataGrid
|
||||||
// and a row number, and returns the float values of that row
|
// and a row number, and returns the float values of that row
|
||||||
// in a mat64.Dense format.
|
// in a mat.Dense format.
|
||||||
func ConvertRowToMat64(attrs []Attribute, f FixedDataGrid, r int) (*mat64.Dense, error) {
|
func ConvertRowToMat64(attrs []Attribute, f FixedDataGrid, r int) (*mat.Dense, error) {
|
||||||
|
|
||||||
err := checkAllAttributesAreFloat(attrs)
|
err := checkAllAttributesAreFloat(attrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -27,7 +27,7 @@ func ConvertRowToMat64(attrs []Attribute, f FixedDataGrid, r int) (*mat64.Dense,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Allocate the return value
|
// Allocate the return value
|
||||||
ret := mat64.NewDense(1, len(attrs), nil)
|
ret := mat.NewDense(1, len(attrs), nil)
|
||||||
|
|
||||||
// Resolve all the attributes
|
// Resolve all the attributes
|
||||||
attrSpecs := ResolveAttributes(f, attrs)
|
attrSpecs := ResolveAttributes(f, attrs)
|
||||||
@ -42,8 +42,8 @@ func ConvertRowToMat64(attrs []Attribute, f FixedDataGrid, r int) (*mat64.Dense,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConvertAllRowsToMat64 takes a list of Attributes and returns a vector
|
// ConvertAllRowsToMat64 takes a list of Attributes and returns a vector
|
||||||
// of all rows in a mat64.Dense format.
|
// of all rows in a mat.Dense format.
|
||||||
func ConvertAllRowsToMat64(attrs []Attribute, f FixedDataGrid) ([]*mat64.Dense, error) {
|
func ConvertAllRowsToMat64(attrs []Attribute, f FixedDataGrid) ([]*mat.Dense, error) {
|
||||||
|
|
||||||
// Check for floats
|
// Check for floats
|
||||||
err := checkAllAttributesAreFloat(attrs)
|
err := checkAllAttributesAreFloat(attrs)
|
||||||
@ -53,14 +53,14 @@ func ConvertAllRowsToMat64(attrs []Attribute, f FixedDataGrid) ([]*mat64.Dense,
|
|||||||
|
|
||||||
// Return value
|
// Return value
|
||||||
_, rows := f.Size()
|
_, rows := f.Size()
|
||||||
ret := make([]*mat64.Dense, rows)
|
ret := make([]*mat.Dense, rows)
|
||||||
|
|
||||||
// Resolve all attributes
|
// Resolve all attributes
|
||||||
attrSpecs := ResolveAttributes(f, attrs)
|
attrSpecs := ResolveAttributes(f, attrs)
|
||||||
|
|
||||||
// Set the values in each return value
|
// Set the values in each return value
|
||||||
for i := 0; i < rows; i++ {
|
for i := 0; i < rows; i++ {
|
||||||
cur := mat64.NewDense(1, len(attrs), nil)
|
cur := mat.NewDense(1, len(attrs), nil)
|
||||||
for j, a := range attrSpecs {
|
for j, a := range attrSpecs {
|
||||||
cur.Set(0, j, UnpackBytesToFloat(f.Get(a, i)))
|
cur.Set(0, j, UnpackBytesToFloat(f.Get(a, i)))
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
// An Estimator is object that can ingest some data and train on it.
|
// An Estimator is object that can ingest some data and train on it.
|
||||||
@ -27,7 +27,7 @@ type Model interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BaseEstimator struct {
|
type BaseEstimator struct {
|
||||||
Data *mat64.Dense
|
Data *mat.Dense
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveEstimatorToGob serialises an estimator to a provided filepath, in gob format.
|
// SaveEstimatorToGob serialises an estimator to a provided filepath, in gob format.
|
||||||
|
@ -3,18 +3,18 @@ package base
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Mat64Instances struct {
|
type Mat64Instances struct {
|
||||||
attributes []Attribute
|
attributes []Attribute
|
||||||
classAttrs map[int]bool
|
classAttrs map[int]bool
|
||||||
Data *mat64.Dense
|
Data *mat.Dense
|
||||||
rows int
|
rows int
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstancesFromMat64 returns a new Mat64Instances from a literal provided.
|
// InstancesFromMat64 returns a new Mat64Instances from a literal provided.
|
||||||
func InstancesFromMat64(rows, cols int, data *mat64.Dense) *Mat64Instances {
|
func InstancesFromMat64(rows, cols int, data *mat.Dense) *Mat64Instances {
|
||||||
|
|
||||||
var ret Mat64Instances
|
var ret Mat64Instances
|
||||||
for i := 0; i < cols; i++ {
|
for i := 0; i < cols; i++ {
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package base
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gonum/matrix/mat64"
|
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
|
"gonum.org/v1/gonum/mat"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInlineMat64Creation(t *testing.T) {
|
func TestInlineMat64Creation(t *testing.T) {
|
||||||
|
|
||||||
Convey("Given a literal array...", t, func() {
|
Convey("Given a literal array...", t, func() {
|
||||||
mat := mat64.NewDense(4, 3, []float64{
|
mat := mat.NewDense(4, 3, []float64{
|
||||||
1, 0, 1,
|
1, 0, 1,
|
||||||
0, 1, 1,
|
0, 1, 1,
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
|
@ -72,7 +72,7 @@ func tarPrefix(prefix string, suffix string) string {
|
|||||||
if prefix == "" {
|
if prefix == "" {
|
||||||
return suffix
|
return suffix
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s/%s")
|
return fmt.Sprintf("%s/%s", prefix, suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClassifierMetadataV1 is what gets written into METADATA
|
// ClassifierMetadataV1 is what gets written into METADATA
|
||||||
|
@ -164,16 +164,19 @@ func DeserializeInstancesFromTarReader(tr *FunctionalTarReader, prefix string) (
|
|||||||
|
|
||||||
// Finally, read the values out of the data section
|
// Finally, read the values out of the data section
|
||||||
for i := 0; i < rowCount; i++ {
|
for i := 0; i < rowCount; i++ {
|
||||||
for _, s := range specs {
|
for j, s := range specs {
|
||||||
r := ret.Get(s, i)
|
r := ret.Get(s, i)
|
||||||
n, err := reader.Read(r)
|
n, err := reader.Read(r)
|
||||||
if n != len(r) {
|
if n != len(r) {
|
||||||
return nil, fmt.Errorf("Expected %d bytes (read %d) on row %d", len(r), n, i)
|
return nil, WrapError(fmt.Errorf("Expected %d bytes (read %d) on row %d", len(r), n, i))
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Read error: %s", err)
|
|
||||||
}
|
}
|
||||||
ret.Set(s, i, r)
|
ret.Set(s, i, r)
|
||||||
|
if err != nil {
|
||||||
|
if i == rowCount-1 && j == len(specs)-1 && err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return nil, WrapError(fmt.Errorf("Read error in data section (at row %d from %d, attr %d from %d): %s", i, rowCount, j, len(specs), err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,6 +303,9 @@ func SerializeInstancesToTarWriter(inst FixedDataGrid, tw *tar.Writer, prefix st
|
|||||||
}
|
}
|
||||||
|
|
||||||
allSpecs := ResolveAttributes(inst, allAttrs)
|
allSpecs := ResolveAttributes(inst, allAttrs)
|
||||||
|
if len(allSpecs) != len(allAttrs) {
|
||||||
|
return WrapError(fmt.Errorf("Error resolving all Attributes: resolved %d, expected %d", len(allSpecs), len(allAttrs)))
|
||||||
|
}
|
||||||
|
|
||||||
// First, estimate the amount of data we'll need...
|
// First, estimate the amount of data we'll need...
|
||||||
dataLength := int64(0)
|
dataLength := int64(0)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package clustering
|
package clustering
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
"github.com/sjwhitworth/golearn/base"
|
"github.com/sjwhitworth/golearn/base"
|
||||||
"github.com/sjwhitworth/golearn/metrics/pairwise"
|
"github.com/sjwhitworth/golearn/metrics/pairwise"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -22,7 +22,7 @@ type DBSCANParameters struct {
|
|||||||
MinCount int
|
MinCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
func regionQuery(p int, ret *big.Int, dist *mat64.Dense, eps float64) *big.Int {
|
func regionQuery(p int, ret *big.Int, dist *mat.Dense, eps float64) *big.Int {
|
||||||
rows, _ := dist.Dims()
|
rows, _ := dist.Dims()
|
||||||
// Return any points within the Eps neighbourhood
|
// Return any points within the Eps neighbourhood
|
||||||
for i := 0; i < rows; i++ {
|
for i := 0; i < rows; i++ {
|
||||||
@ -33,7 +33,7 @@ func regionQuery(p int, ret *big.Int, dist *mat64.Dense, eps float64) *big.Int {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func computePairwiseDistances(inst base.FixedDataGrid, attrs []base.Attribute, metric pairwise.PairwiseDistanceFunc) (*mat64.Dense, error) {
|
func computePairwiseDistances(inst base.FixedDataGrid, attrs []base.Attribute, metric pairwise.PairwiseDistanceFunc) (*mat.Dense, error) {
|
||||||
// Compute pair-wise distances
|
// Compute pair-wise distances
|
||||||
// First convert everything to floats
|
// First convert everything to floats
|
||||||
mats, err := base.ConvertAllRowsToMat64(attrs, inst)
|
mats, err := base.ConvertAllRowsToMat64(attrs, inst)
|
||||||
@ -43,7 +43,7 @@ func computePairwiseDistances(inst base.FixedDataGrid, attrs []base.Attribute, m
|
|||||||
|
|
||||||
// Next, do an n^2 computation of all pairwise distances
|
// Next, do an n^2 computation of all pairwise distances
|
||||||
_, rows := inst.Size()
|
_, rows := inst.Size()
|
||||||
dist := mat64.NewDense(rows, rows, nil)
|
dist := mat.NewDense(rows, rows, nil)
|
||||||
for i := 0; i < rows; i++ {
|
for i := 0; i < rows; i++ {
|
||||||
for j := i + 1; j < rows; j++ {
|
for j := i + 1; j < rows; j++ {
|
||||||
d := metric.Distance(mats[i], mats[j])
|
d := metric.Distance(mats[i], mats[j])
|
||||||
|
@ -2,7 +2,7 @@ package clustering
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
"github.com/sjwhitworth/golearn/base"
|
"github.com/sjwhitworth/golearn/base"
|
||||||
"github.com/sjwhitworth/golearn/metrics/pairwise"
|
"github.com/sjwhitworth/golearn/metrics/pairwise"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
@ -76,8 +76,8 @@ func TestDBSCANDistanceMetric(t *testing.T) {
|
|||||||
|
|
||||||
Convey("Check the distance function is sane...", t, func() {
|
Convey("Check the distance function is sane...", t, func() {
|
||||||
|
|
||||||
d1 := mat64.NewDense(1, 2, nil)
|
d1 := mat.NewDense(1, 2, nil)
|
||||||
d2 := mat64.NewDense(1, 2, nil)
|
d2 := mat.NewDense(1, 2, nil)
|
||||||
|
|
||||||
d1.Set(0, 0, 0.494260967249)
|
d1.Set(0, 0, 0.494260967249)
|
||||||
d1.Set(0, 1, 1.45106696541)
|
d1.Set(0, 1, 1.45106696541)
|
||||||
|
@ -2,7 +2,7 @@ package kdtree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
"github.com/sjwhitworth/golearn/metrics/pairwise"
|
"github.com/sjwhitworth/golearn/metrics/pairwise"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
@ -140,8 +140,8 @@ func (t *Tree) Search(k int, disType pairwise.PairwiseDistanceFunc, target []flo
|
|||||||
|
|
||||||
func (t *Tree) searchHandle(k int, disType pairwise.PairwiseDistanceFunc, target []float64, h *heap, n *node) {
|
func (t *Tree) searchHandle(k int, disType pairwise.PairwiseDistanceFunc, target []float64, h *heap, n *node) {
|
||||||
if n.feature == -1 {
|
if n.feature == -1 {
|
||||||
vectorX := mat64.NewDense(len(target), 1, target)
|
vectorX := mat.NewDense(len(target), 1, target)
|
||||||
vectorY := mat64.NewDense(len(target), 1, n.value)
|
vectorY := mat.NewDense(len(target), 1, n.value)
|
||||||
length := disType.Distance(vectorX, vectorY)
|
length := disType.Distance(vectorX, vectorY)
|
||||||
h.insert(n.value, length, n.srcRowNo)
|
h.insert(n.value, length, n.srcRowNo)
|
||||||
return
|
return
|
||||||
@ -157,8 +157,8 @@ func (t *Tree) searchHandle(k int, disType pairwise.PairwiseDistanceFunc, target
|
|||||||
t.searchHandle(k, disType, target, h, n.right)
|
t.searchHandle(k, disType, target, h, n.right)
|
||||||
}
|
}
|
||||||
|
|
||||||
vectorX := mat64.NewDense(len(target), 1, target)
|
vectorX := mat.NewDense(len(target), 1, target)
|
||||||
vectorY := mat64.NewDense(len(target), 1, n.value)
|
vectorY := mat.NewDense(len(target), 1, n.value)
|
||||||
length := disType.Distance(vectorX, vectorY)
|
length := disType.Distance(vectorX, vectorY)
|
||||||
|
|
||||||
if k > h.size() {
|
if k > h.size() {
|
||||||
@ -177,8 +177,8 @@ func (t *Tree) searchHandle(k int, disType pairwise.PairwiseDistanceFunc, target
|
|||||||
t.searchAllNodes(k, disType, target, h, n.left)
|
t.searchAllNodes(k, disType, target, h, n.left)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vectorX = mat64.NewDense(1, 1, []float64{target[n.feature]})
|
vectorX = mat.NewDense(1, 1, []float64{target[n.feature]})
|
||||||
vectorY = mat64.NewDense(1, 1, []float64{n.value[n.feature]})
|
vectorY = mat.NewDense(1, 1, []float64{n.value[n.feature]})
|
||||||
length = disType.Distance(vectorX, vectorY)
|
length = disType.Distance(vectorX, vectorY)
|
||||||
|
|
||||||
if h.maximum().length > length {
|
if h.maximum().length > length {
|
||||||
@ -192,8 +192,8 @@ func (t *Tree) searchHandle(k int, disType pairwise.PairwiseDistanceFunc, target
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tree) searchAllNodes(k int, disType pairwise.PairwiseDistanceFunc, target []float64, h *heap, n *node) {
|
func (t *Tree) searchAllNodes(k int, disType pairwise.PairwiseDistanceFunc, target []float64, h *heap, n *node) {
|
||||||
vectorX := mat64.NewDense(len(target), 1, target)
|
vectorX := mat.NewDense(len(target), 1, target)
|
||||||
vectorY := mat64.NewDense(len(target), 1, n.value)
|
vectorY := mat.NewDense(len(target), 1, n.value)
|
||||||
length := disType.Distance(vectorX, vectorY)
|
length := disType.Distance(vectorX, vectorY)
|
||||||
|
|
||||||
if k > h.size() {
|
if k > h.size() {
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/gonum/matrix"
|
"github.com/gonum/matrix"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
"github.com/sjwhitworth/golearn/base"
|
"github.com/sjwhitworth/golearn/base"
|
||||||
"github.com/sjwhitworth/golearn/kdtree"
|
"github.com/sjwhitworth/golearn/kdtree"
|
||||||
"github.com/sjwhitworth/golearn/metrics/pairwise"
|
"github.com/sjwhitworth/golearn/metrics/pairwise"
|
||||||
@ -434,11 +434,11 @@ func (KNN *KNNRegressor) Fit(values []float64, numbers []float64, rows int, cols
|
|||||||
panic(matrix.ErrShape)
|
panic(matrix.ErrShape)
|
||||||
}
|
}
|
||||||
|
|
||||||
KNN.Data = mat64.NewDense(rows, cols, numbers)
|
KNN.Data = mat.NewDense(rows, cols, numbers)
|
||||||
KNN.Values = values
|
KNN.Values = values
|
||||||
}
|
}
|
||||||
|
|
||||||
func (KNN *KNNRegressor) Predict(vector *mat64.Dense, K int) float64 {
|
func (KNN *KNNRegressor) Predict(vector *mat.Dense, K int) float64 {
|
||||||
// Get the number of rows
|
// Get the number of rows
|
||||||
rows, _ := KNN.Data.Dims()
|
rows, _ := KNN.Data.Dims()
|
||||||
rownumbers := make(map[int]float64)
|
rownumbers := make(map[int]float64)
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
_ "github.com/gonum/blas"
|
_ "github.com/gonum/blas"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -59,8 +59,8 @@ func (lr *LinearRegression) Fit(inst base.FixedDataGrid) error {
|
|||||||
|
|
||||||
// Split into two matrices, observed results (dependent variable y)
|
// Split into two matrices, observed results (dependent variable y)
|
||||||
// and the explanatory variables (X) - see http://en.wikipedia.org/wiki/Linear_regression
|
// and the explanatory variables (X) - see http://en.wikipedia.org/wiki/Linear_regression
|
||||||
observed := mat64.NewDense(rows, 1, nil)
|
observed := mat.NewDense(rows, 1, nil)
|
||||||
explVariables := mat64.NewDense(rows, cols, nil)
|
explVariables := mat.NewDense(rows, cols, nil)
|
||||||
|
|
||||||
// Build the observed matrix
|
// Build the observed matrix
|
||||||
inst.MapOverRows(classAttrSpecs, func(row [][]byte, i int) (bool, error) {
|
inst.MapOverRows(classAttrSpecs, func(row [][]byte, i int) (bool, error) {
|
||||||
@ -80,13 +80,13 @@ func (lr *LinearRegression) Fit(inst base.FixedDataGrid) error {
|
|||||||
})
|
})
|
||||||
|
|
||||||
n := cols
|
n := cols
|
||||||
qr := new(mat64.QR)
|
qr := new(mat.QR)
|
||||||
qr.Factorize(explVariables)
|
qr.Factorize(explVariables)
|
||||||
var q, reg mat64.Dense
|
var q, reg mat.Dense
|
||||||
q.QFromQR(qr)
|
qr.QTo(&q)
|
||||||
reg.RFromQR(qr)
|
qr.RTo(®)
|
||||||
|
|
||||||
var transposed, qty mat64.Dense
|
var transposed, qty mat.Dense
|
||||||
transposed.Clone(q.T())
|
transposed.Clone(q.T())
|
||||||
qty.Mul(&transposed, observed)
|
qty.Mul(&transposed, observed)
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ func (m *OneVsAllModel) LoadWithPrefix(reader *base.ClassifierDeserializer, pref
|
|||||||
attrMap := make(map[base.Attribute]base.Attribute)
|
attrMap := make(map[base.Attribute]base.Attribute)
|
||||||
|
|
||||||
for j := 0; j < int(numAttrsInMapU64); j++ {
|
for j := 0; j < int(numAttrsInMapU64); j++ {
|
||||||
mapTupleKey := reader.Prefix(mapPrefix, fmt.Sprintf("%d"))
|
mapTupleKey := reader.Prefix(mapPrefix, fmt.Sprintf("%d", j))
|
||||||
mapKeyKeyKey := reader.Prefix(mapTupleKey, "KEY")
|
mapKeyKeyKey := reader.Prefix(mapTupleKey, "KEY")
|
||||||
mapKeyValKey := reader.Prefix(mapTupleKey, "VAL")
|
mapKeyValKey := reader.Prefix(mapTupleKey, "VAL")
|
||||||
|
|
||||||
@ -289,7 +289,7 @@ func (m *OneVsAllModel) SaveWithPrefix(writer *base.ClassifierSerializer, prefix
|
|||||||
}
|
}
|
||||||
j := 0
|
j := 0
|
||||||
for key := range f.attrs {
|
for key := range f.attrs {
|
||||||
mapTupleKey := writer.Prefix(mapPrefix, fmt.Sprintf("%d"))
|
mapTupleKey := writer.Prefix(mapPrefix, fmt.Sprintf("%d", j))
|
||||||
mapKeyKeyKey := writer.Prefix(mapTupleKey, "KEY")
|
mapKeyKeyKey := writer.Prefix(mapTupleKey, "KEY")
|
||||||
mapKeyValKey := writer.Prefix(mapTupleKey, "VAL")
|
mapKeyValKey := writer.Prefix(mapTupleKey, "VAL")
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/gonum/matrix"
|
"github.com/gonum/matrix"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Chebyshev struct{}
|
type Chebyshev struct{}
|
||||||
@ -13,7 +13,7 @@ func NewChebyshev() *Chebyshev {
|
|||||||
return &Chebyshev{}
|
return &Chebyshev{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chebyshev) Distance(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (c *Chebyshev) Distance(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
r1, c1 := vectorX.Dims()
|
r1, c1 := vectorX.Dims()
|
||||||
r2, c2 := vectorY.Dims()
|
r2, c2 := vectorY.Dims()
|
||||||
if r1 != r2 || c1 != c2 {
|
if r1 != r2 || c1 != c2 {
|
||||||
|
@ -3,17 +3,17 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChebyshev(t *testing.T) {
|
func TestChebyshev(t *testing.T) {
|
||||||
var vectorX, vectorY *mat64.Dense
|
var vectorX, vectorY *mat.Dense
|
||||||
chebyshev := NewChebyshev()
|
chebyshev := NewChebyshev()
|
||||||
|
|
||||||
Convey("Given two vectors", t, func() {
|
Convey("Given two vectors", t, func() {
|
||||||
vectorX = mat64.NewDense(4, 1, []float64{1, 2, 3, 4})
|
vectorX = mat.NewDense(4, 1, []float64{1, 2, 3, 4})
|
||||||
vectorY = mat64.NewDense(4, 1, []float64{-5, -6, 7, 8})
|
vectorY = mat.NewDense(4, 1, []float64{-5, -6, 7, 8})
|
||||||
|
|
||||||
Convey("When calculating distance with two vectors", func() {
|
Convey("When calculating distance with two vectors", func() {
|
||||||
result := chebyshev.Distance(vectorX, vectorY)
|
result := chebyshev.Distance(vectorX, vectorY)
|
||||||
|
@ -3,7 +3,7 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cosine struct{}
|
type Cosine struct{}
|
||||||
@ -13,17 +13,17 @@ func NewCosine() *Cosine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dot computes dot value of vectorX and vectorY.
|
// Dot computes dot value of vectorX and vectorY.
|
||||||
func (c *Cosine) Dot(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (c *Cosine) Dot(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
subVector := mat64.NewDense(0, 0, nil)
|
subVector := mat.NewDense(0, 0, nil)
|
||||||
subVector.MulElem(vectorX, vectorY)
|
subVector.MulElem(vectorX, vectorY)
|
||||||
result := mat64.Sum(subVector)
|
result := mat.Sum(subVector)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distance computes Cosine distance.
|
// Distance computes Cosine distance.
|
||||||
// It will return distance which represented as 1-cos() (ranged from 0 to 2).
|
// It will return distance which represented as 1-cos() (ranged from 0 to 2).
|
||||||
func (c *Cosine) Distance(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (c *Cosine) Distance(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
dotXY := c.Dot(vectorX, vectorY)
|
dotXY := c.Dot(vectorX, vectorY)
|
||||||
lengthX := math.Sqrt(c.Dot(vectorX, vectorX))
|
lengthX := math.Sqrt(c.Dot(vectorX, vectorX))
|
||||||
lengthY := math.Sqrt(c.Dot(vectorY, vectorY))
|
lengthY := math.Sqrt(c.Dot(vectorY, vectorY))
|
||||||
|
@ -3,17 +3,17 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCosine(t *testing.T) {
|
func TestCosine(t *testing.T) {
|
||||||
var vectorX, vectorY *mat64.Dense
|
var vectorX, vectorY *mat.Dense
|
||||||
cosine := NewCosine()
|
cosine := NewCosine()
|
||||||
|
|
||||||
Convey("Given two vectors", t, func() {
|
Convey("Given two vectors", t, func() {
|
||||||
vectorX = mat64.NewDense(3, 1, []float64{1, 2, 3})
|
vectorX = mat.NewDense(3, 1, []float64{1, 2, 3})
|
||||||
vectorY = mat64.NewDense(3, 1, []float64{2, 4, 6})
|
vectorY = mat.NewDense(3, 1, []float64{2, 4, 6})
|
||||||
|
|
||||||
Convey("When doing inner Dot", func() {
|
Convey("When doing inner Dot", func() {
|
||||||
result := cosine.Dot(vectorX, vectorY)
|
result := cosine.Dot(vectorX, vectorY)
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/gonum/matrix"
|
"github.com/gonum/matrix"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cranberra struct{}
|
type Cranberra struct{}
|
||||||
@ -20,7 +20,7 @@ func cranberraDistanceStep(num float64, denom float64) float64 {
|
|||||||
return num / denom
|
return num / denom
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cranberra) Distance(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (c *Cranberra) Distance(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
r1, c1 := vectorX.Dims()
|
r1, c1 := vectorX.Dims()
|
||||||
r2, c2 := vectorY.Dims()
|
r2, c2 := vectorY.Dims()
|
||||||
if r1 != r2 || c1 != c2 {
|
if r1 != r2 || c1 != c2 {
|
||||||
|
@ -3,16 +3,16 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCranberrra(t *testing.T) {
|
func TestCranberrra(t *testing.T) {
|
||||||
var vectorX, vectorY *mat64.Dense
|
var vectorX, vectorY *mat.Dense
|
||||||
cranberra := NewCranberra()
|
cranberra := NewCranberra()
|
||||||
|
|
||||||
Convey("Given two vectors that are same", t, func() {
|
Convey("Given two vectors that are same", t, func() {
|
||||||
vec := mat64.NewDense(7, 1, []float64{0, 1, -2, 3.4, 5, -6.7, 89})
|
vec := mat.NewDense(7, 1, []float64{0, 1, -2, 3.4, 5, -6.7, 89})
|
||||||
distance := cranberra.Distance(vec, vec)
|
distance := cranberra.Distance(vec, vec)
|
||||||
|
|
||||||
Convey("The result should be 0", func() {
|
Convey("The result should be 0", func() {
|
||||||
@ -21,8 +21,8 @@ func TestCranberrra(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("Given two vectors", t, func() {
|
Convey("Given two vectors", t, func() {
|
||||||
vectorX = mat64.NewDense(5, 1, []float64{1, 2, 3, 4, 9})
|
vectorX = mat.NewDense(5, 1, []float64{1, 2, 3, 4, 9})
|
||||||
vectorY = mat64.NewDense(5, 1, []float64{-5, -6, 7, 4, 3})
|
vectorY = mat.NewDense(5, 1, []float64{-5, -6, 7, 4, 3})
|
||||||
|
|
||||||
Convey("When calculating distance with two vectors", func() {
|
Convey("When calculating distance with two vectors", func() {
|
||||||
result := cranberra.Distance(vectorX, vectorY)
|
result := cranberra.Distance(vectorX, vectorY)
|
||||||
|
@ -3,7 +3,7 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Euclidean struct{}
|
type Euclidean struct{}
|
||||||
@ -13,17 +13,17 @@ func NewEuclidean() *Euclidean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InnerProduct computes a Eucledian inner product.
|
// InnerProduct computes a Eucledian inner product.
|
||||||
func (e *Euclidean) InnerProduct(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (e *Euclidean) InnerProduct(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
subVector := mat64.NewDense(0, 0, nil)
|
subVector := mat.NewDense(0, 0, nil)
|
||||||
subVector.MulElem(vectorX, vectorY)
|
subVector.MulElem(vectorX, vectorY)
|
||||||
result := mat64.Sum(subVector)
|
result := mat.Sum(subVector)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distance computes Euclidean distance (also known as L2 distance).
|
// Distance computes Euclidean distance (also known as L2 distance).
|
||||||
func (e *Euclidean) Distance(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (e *Euclidean) Distance(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
subVector := mat64.NewDense(0, 0, nil)
|
subVector := mat.NewDense(0, 0, nil)
|
||||||
subVector.Sub(vectorX, vectorY)
|
subVector.Sub(vectorX, vectorY)
|
||||||
|
|
||||||
result := e.InnerProduct(subVector, subVector)
|
result := e.InnerProduct(subVector, subVector)
|
||||||
|
@ -3,17 +3,17 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEuclidean(t *testing.T) {
|
func TestEuclidean(t *testing.T) {
|
||||||
var vectorX, vectorY *mat64.Dense
|
var vectorX, vectorY *mat.Dense
|
||||||
euclidean := NewEuclidean()
|
euclidean := NewEuclidean()
|
||||||
|
|
||||||
Convey("Given two vectors", t, func() {
|
Convey("Given two vectors", t, func() {
|
||||||
vectorX = mat64.NewDense(3, 1, []float64{1, 2, 3})
|
vectorX = mat.NewDense(3, 1, []float64{1, 2, 3})
|
||||||
vectorY = mat64.NewDense(3, 1, []float64{2, 4, 5})
|
vectorY = mat.NewDense(3, 1, []float64{2, 4, 5})
|
||||||
|
|
||||||
Convey("When doing inner product", func() {
|
Convey("When doing inner product", func() {
|
||||||
result := euclidean.InnerProduct(vectorX, vectorY)
|
result := euclidean.InnerProduct(vectorX, vectorY)
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/gonum/matrix"
|
"github.com/gonum/matrix"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Manhattan struct{}
|
type Manhattan struct{}
|
||||||
@ -15,7 +15,7 @@ func NewManhattan() *Manhattan {
|
|||||||
|
|
||||||
// Distance computes the Manhattan distance, also known as L1 distance.
|
// Distance computes the Manhattan distance, also known as L1 distance.
|
||||||
// == the sum of the absolute values of elements.
|
// == the sum of the absolute values of elements.
|
||||||
func (m *Manhattan) Distance(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (m *Manhattan) Distance(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
r1, c1 := vectorX.Dims()
|
r1, c1 := vectorX.Dims()
|
||||||
r2, c2 := vectorY.Dims()
|
r2, c2 := vectorY.Dims()
|
||||||
if r1 != r2 || c1 != c2 {
|
if r1 != r2 || c1 != c2 {
|
||||||
|
@ -3,16 +3,16 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestManhattan(t *testing.T) {
|
func TestManhattan(t *testing.T) {
|
||||||
var vectorX, vectorY *mat64.Dense
|
var vectorX, vectorY *mat.Dense
|
||||||
manhattan := NewManhattan()
|
manhattan := NewManhattan()
|
||||||
|
|
||||||
Convey("Given two vectors that are same", t, func() {
|
Convey("Given two vectors that are same", t, func() {
|
||||||
vec := mat64.NewDense(7, 1, []float64{0, 1, -2, 3.4, 5, -6.7, 89})
|
vec := mat.NewDense(7, 1, []float64{0, 1, -2, 3.4, 5, -6.7, 89})
|
||||||
distance := manhattan.Distance(vec, vec)
|
distance := manhattan.Distance(vec, vec)
|
||||||
|
|
||||||
Convey("The result should be 0", func() {
|
Convey("The result should be 0", func() {
|
||||||
@ -21,8 +21,8 @@ func TestManhattan(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("Given two vectors", t, func() {
|
Convey("Given two vectors", t, func() {
|
||||||
vectorX = mat64.NewDense(3, 1, []float64{2, 2, 3})
|
vectorX = mat.NewDense(3, 1, []float64{2, 2, 3})
|
||||||
vectorY = mat64.NewDense(3, 1, []float64{1, 4, 5})
|
vectorY = mat.NewDense(3, 1, []float64{1, 4, 5})
|
||||||
|
|
||||||
Convey("When calculating distance with column vectors", func() {
|
Convey("When calculating distance with column vectors", func() {
|
||||||
result := manhattan.Distance(vectorX, vectorY)
|
result := manhattan.Distance(vectorX, vectorY)
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
package pairwise
|
package pairwise
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PairwiseDistanceFunc interface {
|
type PairwiseDistanceFunc interface {
|
||||||
Distance(vectorX *mat64.Dense, vectorY *mat64.Dense) float64
|
Distance(vectorX *mat.Dense, vectorY *mat.Dense) float64
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PolyKernel struct {
|
type PolyKernel struct {
|
||||||
@ -17,18 +17,18 @@ func NewPolyKernel(degree int) *PolyKernel {
|
|||||||
|
|
||||||
// InnerProduct computes the inner product through a kernel trick
|
// InnerProduct computes the inner product through a kernel trick
|
||||||
// K(x, y) = (x^T y + 1)^d
|
// K(x, y) = (x^T y + 1)^d
|
||||||
func (p *PolyKernel) InnerProduct(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (p *PolyKernel) InnerProduct(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
subVectorX := vectorX.ColView(0)
|
subVectorX := vectorX.ColView(0)
|
||||||
subVectorY := vectorY.ColView(0)
|
subVectorY := vectorY.ColView(0)
|
||||||
result := mat64.Dot(subVectorX, subVectorY)
|
result := mat.Dot(subVectorX, subVectorY)
|
||||||
result = math.Pow(result+1, float64(p.degree))
|
result = math.Pow(result+1, float64(p.degree))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distance computes distance under the polynomial kernel (maybe not needed?)
|
// Distance computes distance under the polynomial kernel (maybe not needed?)
|
||||||
func (p *PolyKernel) Distance(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (p *PolyKernel) Distance(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
subVector := mat64.NewDense(0, 0, nil)
|
subVector := mat.NewDense(0, 0, nil)
|
||||||
subVector.Sub(vectorX, vectorY)
|
subVector.Sub(vectorX, vectorY)
|
||||||
result := p.InnerProduct(subVector, subVector)
|
result := p.InnerProduct(subVector, subVector)
|
||||||
|
|
||||||
|
@ -3,17 +3,17 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPolyKernel(t *testing.T) {
|
func TestPolyKernel(t *testing.T) {
|
||||||
var vectorX, vectorY *mat64.Dense
|
var vectorX, vectorY *mat.Dense
|
||||||
polyKernel := NewPolyKernel(3)
|
polyKernel := NewPolyKernel(3)
|
||||||
|
|
||||||
Convey("Given two vectors", t, func() {
|
Convey("Given two vectors", t, func() {
|
||||||
vectorX = mat64.NewDense(3, 1, []float64{1, 2, 3})
|
vectorX = mat.NewDense(3, 1, []float64{1, 2, 3})
|
||||||
vectorY = mat64.NewDense(3, 1, []float64{2, 4, 5})
|
vectorY = mat.NewDense(3, 1, []float64{2, 4, 5})
|
||||||
|
|
||||||
Convey("When doing inner product", func() {
|
Convey("When doing inner product", func() {
|
||||||
result := polyKernel.InnerProduct(vectorX, vectorY)
|
result := polyKernel.InnerProduct(vectorX, vectorY)
|
||||||
|
@ -3,7 +3,7 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RBFKernel struct {
|
type RBFKernel struct {
|
||||||
@ -17,7 +17,7 @@ func NewRBFKernel(gamma float64) *RBFKernel {
|
|||||||
|
|
||||||
// InnerProduct computes the inner product through a kernel trick
|
// InnerProduct computes the inner product through a kernel trick
|
||||||
// K(x, y) = exp(-gamma * ||x - y||^2)
|
// K(x, y) = exp(-gamma * ||x - y||^2)
|
||||||
func (r *RBFKernel) InnerProduct(vectorX *mat64.Dense, vectorY *mat64.Dense) float64 {
|
func (r *RBFKernel) InnerProduct(vectorX *mat.Dense, vectorY *mat.Dense) float64 {
|
||||||
euclidean := NewEuclidean()
|
euclidean := NewEuclidean()
|
||||||
distance := euclidean.Distance(vectorX, vectorY)
|
distance := euclidean.Distance(vectorX, vectorY)
|
||||||
|
|
||||||
|
@ -3,17 +3,17 @@ package pairwise
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRBFKernel(t *testing.T) {
|
func TestRBFKernel(t *testing.T) {
|
||||||
var vectorX, vectorY *mat64.Dense
|
var vectorX, vectorY *mat.Dense
|
||||||
rbfKernel := NewRBFKernel(0.1)
|
rbfKernel := NewRBFKernel(0.1)
|
||||||
|
|
||||||
Convey("Given two vectors", t, func() {
|
Convey("Given two vectors", t, func() {
|
||||||
vectorX = mat64.NewDense(3, 1, []float64{1, 2, 3})
|
vectorX = mat.NewDense(3, 1, []float64{1, 2, 3})
|
||||||
vectorY = mat64.NewDense(3, 1, []float64{2, 4, 5})
|
vectorY = mat.NewDense(3, 1, []float64{2, 4, 5})
|
||||||
|
|
||||||
Convey("When doing inner product", func() {
|
Convey("When doing inner product", func() {
|
||||||
result := rbfKernel.InnerProduct(vectorX, vectorY)
|
result := rbfKernel.InnerProduct(vectorX, vectorY)
|
||||||
|
@ -212,7 +212,7 @@ func (nb *BernoulliNBClassifier) Fit(X base.FixedDataGrid) {
|
|||||||
docsContainingTerm := make(map[string][]int)
|
docsContainingTerm := make(map[string][]int)
|
||||||
|
|
||||||
// This algorithm could be vectorized after binarizing the data
|
// This algorithm could be vectorized after binarizing the data
|
||||||
// matrix. Since mat64 doesn't have this function, a iterative
|
// matrix. Since mat doesn't have this function, a iterative
|
||||||
// version is used.
|
// version is used.
|
||||||
X.MapOverRows(featAttrSpecs, func(docVector [][]byte, r int) (bool, error) {
|
X.MapOverRows(featAttrSpecs, func(docVector [][]byte, r int) (bool, error) {
|
||||||
class := base.GetClass(X, r)
|
class := base.GetClass(X, r)
|
||||||
|
@ -2,7 +2,7 @@ package neural
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
"github.com/sjwhitworth/golearn/base"
|
"github.com/sjwhitworth/golearn/base"
|
||||||
"github.com/sjwhitworth/golearn/filters"
|
"github.com/sjwhitworth/golearn/filters"
|
||||||
"math"
|
"math"
|
||||||
@ -105,7 +105,7 @@ func (m *MultiLayerNet) Predict(X base.FixedDataGrid) base.FixedDataGrid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the activation vector
|
// Create the activation vector
|
||||||
a := mat64.NewDense(m.network.size, 1, make([]float64, m.network.size))
|
a := mat.NewDense(m.network.size, 1, make([]float64, m.network.size))
|
||||||
|
|
||||||
// Resolve the input AttributeSpecs
|
// Resolve the input AttributeSpecs
|
||||||
inputAs := base.ResolveAttributes(insts, inputAttrs)
|
inputAs := base.ResolveAttributes(insts, inputAttrs)
|
||||||
@ -277,9 +277,9 @@ func (m *MultiLayerNet) Fit(X base.FixedDataGrid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the training activation vector
|
// Create the training activation vector
|
||||||
trainVec := mat64.NewDense(size, 1, make([]float64, size))
|
trainVec := mat.NewDense(size, 1, make([]float64, size))
|
||||||
// Create the error vector
|
// Create the error vector
|
||||||
errVec := mat64.NewDense(size, 1, make([]float64, size))
|
errVec := mat.NewDense(size, 1, make([]float64, size))
|
||||||
|
|
||||||
// Resolve training AttributeSpecs
|
// Resolve training AttributeSpecs
|
||||||
trainAs := base.ResolveAllAttributes(insts)
|
trainAs := base.ResolveAllAttributes(insts)
|
||||||
@ -322,7 +322,7 @@ func (m *MultiLayerNet) Fit(X base.FixedDataGrid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update total error
|
// Update total error
|
||||||
totalError += math.Abs(mat64.Sum(errVec))
|
totalError += math.Abs(mat.Sum(errVec))
|
||||||
|
|
||||||
// Back-propagate the error
|
// Back-propagate the error
|
||||||
b := m.network.Error(trainVec, errVec, totalLayers)
|
b := m.network.Error(trainVec, errVec, totalLayers)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package neural
|
package neural
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
"github.com/sjwhitworth/golearn/base"
|
"github.com/sjwhitworth/golearn/base"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
"testing"
|
"testing"
|
||||||
@ -129,7 +129,7 @@ func TestLayeredXOR(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
out := mat64.NewDense(6, 1, []float64{1.0, 0.0, 0.0, 0.0, 0.0, 0.0})
|
out := mat.NewDense(6, 1, []float64{1.0, 0.0, 0.0, 0.0, 0.0, 0.0})
|
||||||
net.network.Activate(out, 2)
|
net.network.Activate(out, 2)
|
||||||
So(out.At(5, 0), ShouldAlmostEqual, 1.0, 0.1)
|
So(out.At(5, 0), ShouldAlmostEqual, 1.0, 0.1)
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ func TestLayeredXORInline(t *testing.T) {
|
|||||||
|
|
||||||
Convey("Given an inline XOR dataset...", t, func() {
|
Convey("Given an inline XOR dataset...", t, func() {
|
||||||
|
|
||||||
data := mat64.NewDense(4, 3, []float64{
|
data := mat.NewDense(4, 3, []float64{
|
||||||
1, 0, 1,
|
1, 0, 1,
|
||||||
0, 1, 1,
|
0, 1, 1,
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
@ -186,7 +186,7 @@ func TestLayeredXORInline(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
out := mat64.NewDense(6, 1, []float64{1.0, 0.0, 0.0, 0.0, 0.0, 0.0})
|
out := mat.NewDense(6, 1, []float64{1.0, 0.0, 0.0, 0.0, 0.0, 0.0})
|
||||||
net.network.Activate(out, 2)
|
net.network.Activate(out, 2)
|
||||||
So(out.At(5, 0), ShouldAlmostEqual, 1.0, 0.1)
|
So(out.At(5, 0), ShouldAlmostEqual, 1.0, 0.1)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package neural
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -11,8 +11,8 @@ import (
|
|||||||
// Weights are stored in a dense matrix, each can have its own
|
// Weights are stored in a dense matrix, each can have its own
|
||||||
// NeuralFunction.
|
// NeuralFunction.
|
||||||
type Network struct {
|
type Network struct {
|
||||||
origWeights *mat64.Dense
|
origWeights *mat.Dense
|
||||||
weights *mat64.Dense // n * n
|
weights *mat.Dense // n * n
|
||||||
biases []float64 // n for each neuron
|
biases []float64 // n for each neuron
|
||||||
funcs []NeuralFunction // for each neuron
|
funcs []NeuralFunction // for each neuron
|
||||||
size int
|
size int
|
||||||
@ -27,7 +27,7 @@ type Network struct {
|
|||||||
// connected to themselves for propagation.
|
// connected to themselves for propagation.
|
||||||
func NewNetwork(size int, input int, f NeuralFunction) *Network {
|
func NewNetwork(size int, input int, f NeuralFunction) *Network {
|
||||||
ret := new(Network)
|
ret := new(Network)
|
||||||
ret.weights = mat64.NewDense(size, size, make([]float64, size*size))
|
ret.weights = mat.NewDense(size, size, make([]float64, size*size))
|
||||||
ret.biases = make([]float64, size)
|
ret.biases = make([]float64, size)
|
||||||
ret.funcs = make([]NeuralFunction, size)
|
ret.funcs = make([]NeuralFunction, size)
|
||||||
ret.size = size
|
ret.size = size
|
||||||
@ -104,7 +104,7 @@ func (n *Network) GetBias(node int) float64 {
|
|||||||
// should be set to the number of layers.
|
// should be set to the number of layers.
|
||||||
//
|
//
|
||||||
// This function overwrites whatever's stored in its first argument.
|
// This function overwrites whatever's stored in its first argument.
|
||||||
func (n *Network) Activate(with *mat64.Dense, maxIterations int) {
|
func (n *Network) Activate(with *mat.Dense, maxIterations int) {
|
||||||
|
|
||||||
// Add bias and feed to activation
|
// Add bias and feed to activation
|
||||||
biasFunc := func(r, c int, v float64) float64 {
|
biasFunc := func(r, c int, v float64) float64 {
|
||||||
@ -114,7 +114,7 @@ func (n *Network) Activate(with *mat64.Dense, maxIterations int) {
|
|||||||
return n.funcs[r].Forward(v)
|
return n.funcs[r].Forward(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp := new(mat64.Dense)
|
tmp := new(mat.Dense)
|
||||||
tmp.Clone(with)
|
tmp.Clone(with)
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
@ -128,10 +128,10 @@ func (n *Network) Activate(with *mat64.Dense, maxIterations int) {
|
|||||||
// UpdateWeights takes an output size * 1 output vector and a size * 1
|
// UpdateWeights takes an output size * 1 output vector and a size * 1
|
||||||
// back-propagated error vector, as well as a learnRate and updates
|
// back-propagated error vector, as well as a learnRate and updates
|
||||||
// the internal weights matrix.
|
// the internal weights matrix.
|
||||||
func (n *Network) UpdateWeights(out, err *mat64.Dense, learnRate float64) {
|
func (n *Network) UpdateWeights(out, err *mat.Dense, learnRate float64) {
|
||||||
|
|
||||||
if n.origWeights == nil {
|
if n.origWeights == nil {
|
||||||
n.origWeights = mat64.DenseCopyOf(n.weights)
|
n.origWeights = mat.DenseCopyOf(n.weights)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply that by the learning rate
|
// Multiply that by the learning rate
|
||||||
@ -151,7 +151,7 @@ func (n *Network) UpdateWeights(out, err *mat64.Dense, learnRate float64) {
|
|||||||
|
|
||||||
// UpdateBias computes B = B + l.E and updates the bias weights
|
// UpdateBias computes B = B + l.E and updates the bias weights
|
||||||
// from a size * 1 back-propagated error vector.
|
// from a size * 1 back-propagated error vector.
|
||||||
func (n *Network) UpdateBias(err *mat64.Dense, learnRate float64) {
|
func (n *Network) UpdateBias(err *mat.Dense, learnRate float64) {
|
||||||
|
|
||||||
for i, b := range n.biases {
|
for i, b := range n.biases {
|
||||||
if i < n.input {
|
if i < n.input {
|
||||||
@ -172,11 +172,11 @@ func (n *Network) UpdateBias(err *mat64.Dense, learnRate float64) {
|
|||||||
//
|
//
|
||||||
// If the network is conceptually organised into n layers, maxIterations
|
// If the network is conceptually organised into n layers, maxIterations
|
||||||
// should be set to n.
|
// should be set to n.
|
||||||
func (n *Network) Error(outArg, errArg *mat64.Dense, maxIterations int) *mat64.Dense {
|
func (n *Network) Error(outArg, errArg *mat.Dense, maxIterations int) *mat.Dense {
|
||||||
|
|
||||||
// Copy the arguments
|
// Copy the arguments
|
||||||
out := mat64.DenseCopyOf(outArg)
|
out := mat.DenseCopyOf(outArg)
|
||||||
err := mat64.DenseCopyOf(errArg)
|
err := mat.DenseCopyOf(errArg)
|
||||||
|
|
||||||
// err should be the difference between observed and expected
|
// err should be the difference between observed and expected
|
||||||
// for observation nodes only (everything else should be zero)
|
// for observation nodes only (everything else should be zero)
|
||||||
@ -187,7 +187,7 @@ func (n *Network) Error(outArg, errArg *mat64.Dense, maxIterations int) *mat64.D
|
|||||||
panic("Unsupported output size")
|
panic("Unsupported output size")
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := mat64.NewDense(outRows, 1, make([]float64, outRows))
|
ret := mat.NewDense(outRows, 1, make([]float64, outRows))
|
||||||
|
|
||||||
// Do differential calculation
|
// Do differential calculation
|
||||||
diffFunc := func(r, c int, v float64) float64 {
|
diffFunc := func(r, c int, v float64) float64 {
|
||||||
@ -196,7 +196,7 @@ func (n *Network) Error(outArg, errArg *mat64.Dense, maxIterations int) *mat64.D
|
|||||||
out.Apply(diffFunc, out)
|
out.Apply(diffFunc, out)
|
||||||
|
|
||||||
// Transpose weights matrix
|
// Transpose weights matrix
|
||||||
reverseWeights := mat64.DenseCopyOf(n.weights)
|
reverseWeights := mat.DenseCopyOf(n.weights)
|
||||||
reverseWeights.Clone(n.weights.T())
|
reverseWeights.Clone(n.weights.T())
|
||||||
|
|
||||||
// We only need a certain number of passes
|
// We only need a certain number of passes
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package neural
|
package neural
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -29,7 +29,7 @@ func TestNetworkWith1Layer(t *testing.T) {
|
|||||||
|
|
||||||
// Create the Activation vector
|
// Create the Activation vector
|
||||||
// NewDense is rows then columns
|
// NewDense is rows then columns
|
||||||
a := mat64.NewDense(6, 1, make([]float64, 6))
|
a := mat.NewDense(6, 1, make([]float64, 6))
|
||||||
// Set is rows then columns
|
// Set is rows then columns
|
||||||
a.Set(0, 0, 1)
|
a.Set(0, 0, 1)
|
||||||
a.Set(2, 0, 1)
|
a.Set(2, 0, 1)
|
||||||
@ -42,7 +42,7 @@ func TestNetworkWith1Layer(t *testing.T) {
|
|||||||
So(a.At(3, 0), ShouldAlmostEqual, 0.332, 0.01)
|
So(a.At(3, 0), ShouldAlmostEqual, 0.332, 0.01)
|
||||||
|
|
||||||
// Set the observed error on the output node
|
// Set the observed error on the output node
|
||||||
e := mat64.NewDense(6, 1, make([]float64, 6))
|
e := mat.NewDense(6, 1, make([]float64, 6))
|
||||||
e.Set(5, 0, 1.0-a.At(5, 0))
|
e.Set(5, 0, 1.0-a.At(5, 0))
|
||||||
|
|
||||||
// Run back-propagated error
|
// Run back-propagated error
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
package neural
|
package neural
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ActivationFunction func(float64) float64
|
type ActivationFunction func(float64) float64
|
||||||
@ -16,4 +16,4 @@ type NeuralFunction struct {
|
|||||||
|
|
||||||
// LayerFuncs are vectorised layer value transformation functions
|
// LayerFuncs are vectorised layer value transformation functions
|
||||||
// (e.g. sigmoid). They must operate in-place.
|
// (e.g. sigmoid). They must operate in-place.
|
||||||
type LayerFunc func(*mat64.Dense)
|
type LayerFunc func(*mat.Dense)
|
||||||
|
35
pca/pca.go
35
pca/pca.go
@ -2,13 +2,12 @@
|
|||||||
package pca
|
package pca
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gonum/matrix"
|
"gonum.org/v1/gonum/mat"
|
||||||
"github.com/gonum/matrix/mat64"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type PCA struct {
|
type PCA struct {
|
||||||
Num_components int
|
Num_components int
|
||||||
svd *mat64.SVD
|
svd *mat.SVD
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of components. 0 - by default, use number of features as number of components
|
// Number of components. 0 - by default, use number of features as number of components
|
||||||
@ -18,19 +17,19 @@ func NewPCA(num_components int) *PCA {
|
|||||||
|
|
||||||
// Fit PCA model and transform data
|
// Fit PCA model and transform data
|
||||||
// Need return is base.FixedDataGrid
|
// Need return is base.FixedDataGrid
|
||||||
func (pca *PCA) FitTransform(X *mat64.Dense) *mat64.Dense {
|
func (pca *PCA) FitTransform(X *mat.Dense) *mat.Dense {
|
||||||
return pca.Fit(X).Transform(X)
|
return pca.Fit(X).Transform(X)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fit PCA model
|
// Fit PCA model
|
||||||
func (pca *PCA) Fit(X *mat64.Dense) *PCA {
|
func (pca *PCA) Fit(X *mat.Dense) *PCA {
|
||||||
// Mean to input data
|
// Mean to input data
|
||||||
M := mean(X)
|
M := mean(X)
|
||||||
X = matrixSubVector(X, M)
|
X = matrixSubVector(X, M)
|
||||||
|
|
||||||
// Get SVD decomposition from data
|
// Get SVD decomposition from data
|
||||||
pca.svd = &mat64.SVD{}
|
pca.svd = &mat.SVD{}
|
||||||
ok := pca.svd.Factorize(X, matrix.SVDThin)
|
ok := pca.svd.Factorize(X, mat.SVDThin)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("Unable to factorize")
|
panic("Unable to factorize")
|
||||||
}
|
}
|
||||||
@ -42,41 +41,41 @@ func (pca *PCA) Fit(X *mat64.Dense) *PCA {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Need return is base.FixedDataGrid
|
// Need return is base.FixedDataGrid
|
||||||
func (pca *PCA) Transform(X *mat64.Dense) *mat64.Dense {
|
func (pca *PCA) Transform(X *mat.Dense) *mat.Dense {
|
||||||
if pca.svd == nil {
|
if pca.svd == nil {
|
||||||
panic("You should to fit PCA model first")
|
panic("You should to fit PCA model first")
|
||||||
}
|
}
|
||||||
|
|
||||||
num_samples, num_features := X.Dims()
|
num_samples, num_features := X.Dims()
|
||||||
|
|
||||||
vTemp := new(mat64.Dense)
|
vTemp := new(mat.Dense)
|
||||||
vTemp.VFromSVD(pca.svd)
|
pca.svd.VTo(vTemp)
|
||||||
//Compute to full data
|
//Compute to full data
|
||||||
if pca.Num_components == 0 || pca.Num_components > num_features {
|
if pca.Num_components == 0 || pca.Num_components > num_features {
|
||||||
return compute(X, vTemp)
|
return compute(X, vTemp)
|
||||||
}
|
}
|
||||||
|
|
||||||
X = compute(X, vTemp)
|
X = compute(X, vTemp)
|
||||||
result := mat64.NewDense(num_samples, pca.Num_components, nil)
|
result := mat.NewDense(num_samples, pca.Num_components, nil)
|
||||||
result.Copy(X.View(0, 0, num_samples, pca.Num_components))
|
result.Copy(X)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
//Helpful private functions
|
//Helpful private functions
|
||||||
|
|
||||||
//Compute mean of the columns of input matrix
|
//Compute mean of the columns of input matrix
|
||||||
func mean(matrix *mat64.Dense) *mat64.Dense {
|
func mean(matrix *mat.Dense) *mat.Dense {
|
||||||
rows, cols := matrix.Dims()
|
rows, cols := matrix.Dims()
|
||||||
meanVector := make([]float64, cols)
|
meanVector := make([]float64, cols)
|
||||||
for i := 0; i < cols; i++ {
|
for i := 0; i < cols; i++ {
|
||||||
sum := mat64.Sum(matrix.ColView(i))
|
sum := mat.Sum(matrix.ColView(i))
|
||||||
meanVector[i] = sum / float64(rows)
|
meanVector[i] = sum / float64(rows)
|
||||||
}
|
}
|
||||||
return mat64.NewDense(1, cols, meanVector)
|
return mat.NewDense(1, cols, meanVector)
|
||||||
}
|
}
|
||||||
|
|
||||||
// After computing of mean, compute: X(input matrix) - X(mean vector)
|
// After computing of mean, compute: X(input matrix) - X(mean vector)
|
||||||
func matrixSubVector(mat, vec *mat64.Dense) *mat64.Dense {
|
func matrixSubVector(mat, vec *mat.Dense) *mat.Dense {
|
||||||
rowsm, colsm := mat.Dims()
|
rowsm, colsm := mat.Dims()
|
||||||
_, colsv := vec.Dims()
|
_, colsv := vec.Dims()
|
||||||
if colsv != colsm {
|
if colsv != colsm {
|
||||||
@ -91,8 +90,8 @@ func matrixSubVector(mat, vec *mat64.Dense) *mat64.Dense {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Multiplication of X(input data) and V(from SVD)
|
//Multiplication of X(input data) and V(from SVD)
|
||||||
func compute(X, Y mat64.Matrix) *mat64.Dense {
|
func compute(X, Y mat.Matrix) *mat.Dense {
|
||||||
var ret mat64.Dense
|
var ret mat.Dense
|
||||||
ret.Mul(X, Y)
|
ret.Mul(X, Y)
|
||||||
return &ret
|
return &ret
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,13 @@ package pca
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPCAWithZeroComponents(t *testing.T) {
|
func TestPCAWithZeroComponents(t *testing.T) {
|
||||||
Convey("Set to pca 0 components with first matrix", t, func() {
|
Convey("Set to pca 0 components with first matrix", t, func() {
|
||||||
X1 := mat64.NewDense(3, 7, []float64{6, 5, 4, 3, 8, 2, 9, 5, 1, 10, 2, 3, 8, 7, 5, 14, 2, 3, 6, 3, 2})
|
X1 := mat.NewDense(3, 7, []float64{6, 5, 4, 3, 8, 2, 9, 5, 1, 10, 2, 3, 8, 7, 5, 14, 2, 3, 6, 3, 2})
|
||||||
pca := NewPCA(0)
|
pca := NewPCA(0)
|
||||||
rows, cols := pca.FitTransform(X1).Dims()
|
rows, cols := pca.FitTransform(X1).Dims()
|
||||||
So(rows, ShouldEqual, 3)
|
So(rows, ShouldEqual, 3)
|
||||||
@ -17,7 +17,7 @@ func TestPCAWithZeroComponents(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("Set to pca 0 components with second matrix", t, func() {
|
Convey("Set to pca 0 components with second matrix", t, func() {
|
||||||
X1 := mat64.NewDense(10, 5, []float64{
|
X1 := mat.NewDense(10, 5, []float64{
|
||||||
0.52984892, 0.1141001, 0.91599294, 0.9574267, 0.15361222,
|
0.52984892, 0.1141001, 0.91599294, 0.9574267, 0.15361222,
|
||||||
0.07057588, 0.46371013, 0.73091854, 0.84641034, 0.08122213,
|
0.07057588, 0.46371013, 0.73091854, 0.84641034, 0.08122213,
|
||||||
0.96221946, 0.60367214, 0.69851546, 0.91965564, 0.27040597,
|
0.96221946, 0.60367214, 0.69851546, 0.91965564, 0.27040597,
|
||||||
@ -37,7 +37,7 @@ func TestPCAWithZeroComponents(t *testing.T) {
|
|||||||
|
|
||||||
func TestPCAWithNComponents(t *testing.T) {
|
func TestPCAWithNComponents(t *testing.T) {
|
||||||
Convey("Set to pca 3 components with 5x5 matrix", t, func() {
|
Convey("Set to pca 3 components with 5x5 matrix", t, func() {
|
||||||
X := mat64.NewDense(5, 5, []float64{
|
X := mat.NewDense(5, 5, []float64{
|
||||||
0.23030838, 0.05669317, 0.3187813, 0.34455114, 0.98062806,
|
0.23030838, 0.05669317, 0.3187813, 0.34455114, 0.98062806,
|
||||||
0.38995469, 0.2996771, 0.99043575, 0.04443827, 0.99527955,
|
0.38995469, 0.2996771, 0.99043575, 0.04443827, 0.99527955,
|
||||||
0.27266308, 0.14068906, 0.46999473, 0.03296131, 0.90855405,
|
0.27266308, 0.14068906, 0.46999473, 0.03296131, 0.90855405,
|
||||||
@ -50,7 +50,7 @@ func TestPCAWithNComponents(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("Set to pca 2 components with 3x5 matrix", t, func() {
|
Convey("Set to pca 2 components with 3x5 matrix", t, func() {
|
||||||
X := mat64.NewDense(3, 5, []float64{
|
X := mat.NewDense(3, 5, []float64{
|
||||||
0.12294845, 0.55170713, 0.67572832, 0.60615516, 0.38184551,
|
0.12294845, 0.55170713, 0.67572832, 0.60615516, 0.38184551,
|
||||||
0.93486821, 0.15120374, 0.89760169, 0.74715672, 0.81373931,
|
0.93486821, 0.15120374, 0.89760169, 0.74715672, 0.81373931,
|
||||||
0.42821569, 0.47457753, 0.18960954, 0.42466159, 0.34166049})
|
0.42821569, 0.47457753, 0.18960954, 0.42466159, 0.34166049})
|
||||||
@ -63,7 +63,7 @@ func TestPCAWithNComponents(t *testing.T) {
|
|||||||
|
|
||||||
func TestPCAFitAndTransformSeparately(t *testing.T) {
|
func TestPCAFitAndTransformSeparately(t *testing.T) {
|
||||||
Convey("Set to pca 3 components with 5x5 matrix", t, func() {
|
Convey("Set to pca 3 components with 5x5 matrix", t, func() {
|
||||||
X := mat64.NewDense(5, 5, []float64{
|
X := mat.NewDense(5, 5, []float64{
|
||||||
0.23030838, 0.05669317, 0.3187813, 0.34455114, 0.98062806,
|
0.23030838, 0.05669317, 0.3187813, 0.34455114, 0.98062806,
|
||||||
0.38995469, 0.2996771, 0.99043575, 0.04443827, 0.99527955,
|
0.38995469, 0.2996771, 0.99043575, 0.04443827, 0.99527955,
|
||||||
0.27266308, 0.14068906, 0.46999473, 0.03296131, 0.90855405,
|
0.27266308, 0.14068906, 0.46999473, 0.03296131, 0.90855405,
|
||||||
|
@ -4,7 +4,7 @@ package utilities
|
|||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/gonum/matrix/mat64"
|
"gonum.org/v1/gonum/mat"
|
||||||
)
|
)
|
||||||
|
|
||||||
type sortedIntMap struct {
|
type sortedIntMap struct {
|
||||||
@ -37,11 +37,12 @@ func SortIntMap(m map[int]float64) []int {
|
|||||||
return sm.s
|
return sm.s
|
||||||
}
|
}
|
||||||
|
|
||||||
func FloatsToMatrix(floats []float64) *mat64.Dense {
|
func FloatsToMatrix(floats []float64) *mat.Dense {
|
||||||
return mat64.NewDense(1, len(floats), floats)
|
return mat.NewDense(1, len(floats), floats)
|
||||||
}
|
}
|
||||||
|
|
||||||
func VectorToMatrix(vector *mat64.Vector) *mat64.Dense {
|
func VectorToMatrix(vector mat.Vector) *mat.Dense {
|
||||||
vec := vector.RawVector()
|
denseCopy := mat.VecDenseCopyOf(vector)
|
||||||
return mat64.NewDense(1, len(vec.Data), vec.Data)
|
vec := denseCopy.RawVector()
|
||||||
|
return mat.NewDense(1, len(vec.Data), vec.Data)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user