/* * MIT License * * Copyright (c) 2019 Alexey Edelev * * This file is part of NeuralNetwork project https://git.semlanik.org/semlanik/NeuralNetwork * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be included in all copies * or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package teach import ( "bufio" "fmt" "log" "os" "strconv" "strings" mat "gonum.org/v1/gonum/mat" ) type TextDataReader struct { dataSet []*mat.Dense result []*mat.Dense index int } func NewTextDataReader(filename string) *TextDataReader { r := &TextDataReader{ index: 0, } r.readData(filename) return r } func (r *TextDataReader) readData(filename string) { inputFile, err := os.Open(filename) if err != nil { log.Fatal(err) } defer inputFile.Close() scanner := bufio.NewScanner(inputFile) scanner.Split(bufio.ScanLines) max := []float64{0.0, 0.0, 0.0, 0.0} for scanner.Scan() { dataLine := scanner.Text() data := strings.Split(dataLine, ",") if len(data) < 5 { fmt.Printf("Garbage record: %s\n", dataLine) continue } var dataRaw []float64 for i := 0; i < 4; i++ { val, err := strconv.ParseFloat(data[i], 64) if err != nil { break } dataRaw = append(dataRaw, val) if max[i] < val { max[i] = val } } if len(dataRaw) < 4 { fmt.Printf("Garbage record: %s\n", dataLine) continue } r.dataSet = append(r.dataSet, mat.NewDense(4, 1, dataRaw)) switch data[4] { case "Iris-setosa": r.result = append(r.result, mat.NewDense(3, 1, []float64{1.0, 0.0, 0.0})) case "Iris-versicolor": r.result = append(r.result, mat.NewDense(3, 1, []float64{0.0, 1.0, 0.0})) case "Iris-virginica": r.result = append(r.result, mat.NewDense(3, 1, []float64{0.0, 0.0, 1.0})) } } //normalize for i := 0; i < len(r.dataSet); i++ { r.dataSet[i].Apply(func(r, _ int, val float64) float64 { return val / max[r] }, r.dataSet[i]) } } func (r *TextDataReader) GetData() *mat.Dense { return r.dataSet[r.index] } func (r *TextDataReader) GetExpect() *mat.Dense { return r.result[r.index] } func (r *TextDataReader) Next() bool { r.index++ if r.index >= len(r.result) { r.index = 0 return false } return true } func (r *TextDataReader) Reset() { r.index = 0 } func (r *TextDataReader) Index() int { return r.index }