Go语言Knn邻近算法

package main
import (
	 ."fmt"
	 "math"
)
//决策因素结构  data  
type Factor struct{
	Id int  				` json:"id" form:"id"`// 主键
	Dishname string			` json:"dishname" form:"dishname"`//菜名
	Culture float64 			` json:"culture" form:"culture"`//文化 
	Tradition float64 		`json:"tradition"` //传统
	Habit float64 			`json:"habit"`//习惯
	Budget float64			`json:"budget"`//预算
	Curious float64			`json:"curious"`//好奇心
	Aesthetic float64		`json:"aesthetic"`//审美
	Bodybuilding float64		`json:"bodybuilding"`//健身
	Health float64			`json:"health"`//健康
	Distance_s	float64	`json:"distance_s"`//距离
}//菜名  res  菜名 距离
type Dish struct{
	Id int				`json:"id"`//主键
	Dishname	string	`json:"dishname"`//菜名
	Value	float64		`json:"value"`//权值
	Distance_s	float64	`json:"distance_s"`//距离
}//读取数据源
func ReadData()  []Factor{
	Printf("Read OK.")
	factors := make([]Factor, 0)
	return factors
}//将数据源分组   一部分33%测试  一部分66%训练
func SplitData(F []Factor) ([]Factor,[]Factor) {
	Printf("Split OK.")
	length:=len(F)
	L1:=int(float64(length)*0.33)
	return F[0:L1],F[L1:length]

}//开方
func InvSqrt(x float64) float64 {
    var xhalf float64 = 0.5*x // get bits for floating VALUE 
    i := math.Float64bits(x) // gives initial guess y0
    i = 0x5f375a86 - (i>>1) // convert bits BACK to float
    x = math.Float64frombits(i) // Newton step, repeating increases accuracy
    x = x*(1.5-xhalf*x*x)
    x = x*(1.5-xhalf*x*x)
    x = x*(1.5-xhalf*x*x)
    return 1/x
}//求距离公式
func Distance(A Factor,B Factor) float64{
	Printf("Distance OK.")
	var sum float64
	sum=0
	sum=(A.Culture-B.Culture)*(A.Culture-B.Culture)+(A.Tradition-B.Tradition)*(A.Tradition-B.Tradition)
	sum=sum+(A.Budget-B.Budget)*(A.Budget-B.Budget)+(A.Habit-B.Habit)*(A.Habit-B.Habit)
	sum=sum+(A.Curious-B.Curious)*(A.Curious-B.Curious)+(A.Aesthetic-B.Aesthetic)*(A.Aesthetic-B.Aesthetic)
	sum=sum+(A.Bodybuilding-B.Bodybuilding)*(A.Bodybuilding-B.Bodybuilding)+(A.Health-B.Health)*(A.Health-B.Health)
	return InvSqrt(sum)
}//排序子算法
func quickSort(A []float64, p int, r int,B []Dish) {
    if p < r {
        q := partition(A, p, r,B)
        Println(q)
        quickSort(A, p, q-1,B)
        quickSort(A, q+1, r,B)
    }
}
func partition(A []float64, p int, r int,B []Dish) int {
    x := A[r-1]
    i := p - 1
    for j := p; j < r-1; j++ {
        if A[j] >= x {
            i += 1
			A[i], A[j] = A[j], A[i]
			B[i], B[j] = B[j], B[i]
        }
    }
	A[i+1], A[r-1] = A[r-1], A[i+1]
	B[i+1], B[r-1] = B[r-1], B[i+1]
    return i + 1
}//排序
func Sort(x []Dish) []Dish {
	date:=make([]float64,len(x))
	for index := 0; index < len(x); index++ {
		date[index]=x[index].Value
	}
    quickSort(date, 0, len(date),x)
	Printf("Sort OK.")
	return x
}//排序权值
func SortEnd(x []Dish) []Dish {
	date:=make([]float64,len(x))
	for index := 0; index < len(x); index++ {
		date[index]=x[index].Distance_s
	}
    quickSort(date, 0, len(date),x)
	Printf("Sort OK.")
	return x
}//取前K个
func Get(k int,A []Dish) []Dish {
	Printf("Get OK.")
	if len(A)<=k {
		return A
	}
	return A[0:k]
}//加权平均 算出权值
func Averange(x[]Dish) []Dish {
	Printf("Averange OK.")
	var sum float64
	for i := 0; i < len(x); i++ {
		sum+=x[i].Distance_s
	}
	for i := 0; i < len(x); i++ {
		x[i].Value=1-(x[i].Distance_s/sum)
	}
	return x
}//Knn汇总最终算法
func Knn(factors []Factor,data Factor) Dish {
	Printf("Knn OK.")
	length:=len(factors)
	dish := make([]Dish, 20)
	//1距离
	for i := 0; i < length; i++ {
		dish[i].Dishname=factors[i].Dishname
		dish[i].Distance_s=Distance(data,factors[i])
	}
	//2排序---升序
	dish1 := make([]Dish, 20)
	dish1=Sort(dish)
	//3取前k个
	k:=5
	dishEnd:=Get(k,dish1)
	//4加权平均
	dishEnd=Averange(dishEnd)
	//5选出最大权值--得出结果
	return	SortEnd(dishEnd)[0]
}
func main()  {
	factors := make([]Factor, 100)
	L1,L2:=SplitData(factors)
	//var end Dish
	end:=Knn(L2,L1[3])
	Println(end)
	// Println(len(L1))
	// Println("OK")
	// Println(len(L2))
}

猜你喜欢

转载自blog.csdn.net/qq_40417296/article/details/89290770
今日推荐