// CompareOutOfSample will compare the current hypothesis function learn by linear regression whith respect to 'f' out of sample func (linreg *LinearRegression) CompareOutOfSample(f linear.LinearFunc, nParams int) float64 { outOfSample := 1000 diff := 0 for i := 0; i < outOfSample; i++ { //var oY int oX := make([]float64, linreg.VectorSize) oX[0] = float64(1) for j := 1; j < len(oX); j++ { oX[j] = linreg.Interval.RandFloat() } gi := float64(0) for j := 0; j < len(oX); j++ { gi += oX[j] * linreg.Wn[j] } if nParams == 2 { if linear.Sign(gi) != int(f(oX[1], oX[2])) { diff++ } } else if nParams == 1 { if linear.Sign(gi) != int(f(oX[1])) { diff++ } } } return float64(diff) / float64(outOfSample) }
// CompareInSample will compare the current hypothesis function learn by linear regression whith respect to 'f' func (linreg *LinearRegression) CompareInSample(f linear.LinearFunc, nParams int) float64 { gInSample := make([]float64, len(linreg.Xn)) fInSample := make([]float64, len(linreg.Xn)) for i := 0; i < len(linreg.Xn); i++ { gi := float64(0) for j := 0; j < len(linreg.Xn[0]); j++ { gi += linreg.Xn[i][j] * linreg.Wn[j] } gInSample[i] = float64(linear.Sign(gi)) if nParams == 2 { fInSample[i] = f(linreg.Xn[i][1], linreg.Xn[i][2]) } else if nParams == 1 { fInSample[i] = f(linreg.Xn[i][1]) } } // measure difference: diff := 0 for i := 0; i < len(linreg.Xn); i++ { if gInSample[i] != fInSample[i] { diff++ } } return float64(diff) / float64(len(linreg.Xn)) }
// EoutFromFile only supports linear regressions with transformed data. // todo:(santiaago) make this more generic. func (linreg *LinearRegression) EoutFromFile(filename string) (float64, error) { file, err := os.Open(filename) if err != nil { log.Fatal(err) } defer file.Close() numError := 0 numberOfLines := 0 scanner := bufio.NewScanner(file) for scanner.Scan() { split := strings.Split(scanner.Text(), " ") var line []string for _, s := range split { cell := strings.Replace(s, " ", "", -1) if len(cell) > 0 { line = append(line, cell) } } var oY int var oX1, oX2 float64 if x1, err := strconv.ParseFloat(line[0], 64); err != nil { fmt.Printf("x1 unable to parse line %d in file %s\n", numberOfLines, filename) return 0, err } else { oX1 = x1 } if x2, err := strconv.ParseFloat(line[1], 64); err != nil { fmt.Printf("x2 unable to parse line %d in file %s\n", numberOfLines, filename) return 0, err } else { oX2 = x2 } oX := linreg.TransformFunction([]float64{float64(1), oX1, oX2}) if y, err := strconv.ParseFloat(line[2], 64); err != nil { fmt.Printf("y unable to parse line %d in file %s\n", numberOfLines, filename) return 0, err } else { oY = int(y) } gi := float64(0) for j := 0; j < len(oX); j++ { gi += oX[j] * linreg.Wn[j] } if linear.Sign(gi) != oY { numError++ } numberOfLines++ } if err := scanner.Err(); err != nil { log.Fatal(err) } return float64(numError) / float64(numberOfLines), nil }
// Hypothesis function h is the hypothesis of the perceptron algorithm. // It takes as arguments vector X and a vector W (w for weight) // function h implements h(x) = sign(w'x) func h(x Point, w Point) int { if len(x) != len(w) { fmt.Println("Panic: vectors x and w should be of same size.") panic(x) } var res float64 = 0 for i := 0; i < len(w); i++ { res = res + w[i]*x[i] } return linear.Sign(res) }
func (linreg *LinearRegression) EValIn() float64 { gInSample := make([]int, len(linreg.XVal)) for i := 0; i < len(linreg.XVal); i++ { gi := float64(0) for j := 0; j < len(linreg.XVal[0]); j++ { gi += linreg.XVal[i][j] * linreg.Wn[j] } gInSample[i] = linear.Sign(gi) } nEin := 0 for i := 0; i < len(gInSample); i++ { if gInSample[i] != linreg.YVal[i] { nEin++ } } return float64(nEin) / float64(len(gInSample)) }
// Eout is the fraction of out of sample points which got misclassified. func (linreg *LinearRegression) Eout() float64 { outOfSample := 1000 numError := 0 for i := 0; i < outOfSample; i++ { var oY int oX := make([]float64, linreg.VectorSize) oX[0] = float64(1) for j := 1; j < len(oX); j++ { oX[j] = linreg.Interval.RandFloat() } flip := 1 if linreg.Noise != 0 { r := rand.New(rand.NewSource(time.Now().UnixNano())) rN := r.Intn(100) if rN < int(math.Ceil(linreg.Noise*100)) { flip = -1 } } // output with potential noise in 'flip' variable if !linreg.TwoParams { oY = evaluate(linreg.TargetFunction, oX) * flip } else { oY = evaluateTwoParams(linreg.TargetFunction, oX) * flip } gi := float64(0) for j := 0; j < len(oX); j++ { gi += oX[j] * linreg.Wn[j] } if linear.Sign(gi) != oY { numError++ } } return float64(numError) / float64(outOfSample) }