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 }