如何从golearn模型获取预测结果?含单样本预测与模型保存需求
GoLearn模型实战:单行无标签数据预测与模型持久化
1. 单行无标签数据预测实现
基于官方KNN Iris示例,要实现单行数据预测,核心是将输入字符串转换为GoLearn兼容的Dataset结构,确保特征维度、类型与训练集完全匹配,再调用模型的Predict方法。
修改后的完整示例代码
package main import ( "log" "os" "strconv" "strings" "github.com/sjwhitworth/golearn/base" "github.com/sjwhitworth/golearn/evaluation" "github.com/sjwhitworth/golearn/knn" ) func main() { // 加载Iris数据集(与官方示例一致) rawData, err := base.ParseCSVToInstances("iris.csv", true) if err != nil { log.Fatal(err) } // 初始化KNN分类器(与官方示例一致) cls := knn.NewKnnClassifier("euclidean", "linear", 2) // 划分训练集和测试集(与官方示例一致) trainData, testData := base.InstancesTrainTestSplit(rawData, 0.70) cls.Fit(trainData) // 官方示例的准确率评估(保留) predictions, err := cls.Predict(testData) if err != nil { log.Fatal(err) } confusionMat, err := evaluation.GetConfusionMatrix(testData, predictions) if err != nil { log.Fatal("Unable to get confusion matrix", err) } log.Println(evaluation.GetSummary(confusionMat)) // -------------------------- 新增:单行数据预测 -------------------------- // 输入的无标签单行数据 inputStr := "5.0,3.6,1.4,0.2" // 分割字符串为浮点型特征数组 featureStrs := strings.Split(inputStr, ",") var floatFeatures []float64 for _, s := range featureStrs { val, err := strconv.ParseFloat(s, 64) if err != nil { log.Fatal("解析输入数据失败:", err) } floatFeatures = append(floatFeatures, val) } // 创建与训练集结构一致的空Dataset predData := base.NewInstancesDataset() // 添加和训练集完全相同的特征属性(顺序不能错) predData.AddAttribute(base.NewFloatAttribute("sepal length")) predData.AddAttribute(base.NewFloatAttribute("sepal width")) predData.AddAttribute(base.NewFloatAttribute("petal length")) predData.AddAttribute(base.NewFloatAttribute("petal width")) predData.AddAttribute(base.NewCategoricalAttribute("class")) // 必须包含标签属性 // 创建无标签实例(标签值临时设为0.0,预测会覆盖) inst := base.NewDenseInstance(0.0) for idx, val := range floatFeatures { inst.Set(idx, val) } // 将实例加入Dataset predData.AddInstance(inst) // 执行预测 singlePred, err := cls.Predict(predData) if err != nil { log.Fatal("预测失败:", err) } // 获取预测结果(索引0对应第一个实例的标签) predLabel := singlePred.Get(0, 0) log.Printf("输入数据 [%s] 的预测类别: %s\n", inputStr, predLabel) }
关键注意点
- 预测用的
Dataset属性顺序、类型必须和训练集完全一致,否则会出现维度不匹配或类型错误。 - 无标签实例的标签值可临时设为任意值,预测时模型会忽略原始标签,输出计算后的预测结果。
2. 模型保存与加载(避免重复训练)
GoLearn的多数模型(包括KnnClassifier)实现了gob序列化接口,可直接将模型序列化到文件,下次使用时加载即可,无需重新训练。
新增模型保存与加载的代码片段
在上述代码基础上,添加以下逻辑:
import "encoding/gob" // 需要新增这个导入 // -------------------------- 新增:模型保存 -------------------------- // 创建模型文件 modelFile, err := os.Create("knn_iris_model.gob") if err != nil { log.Fatal("创建模型文件失败:", err) } defer modelFile.Close() // 使用gob序列化模型 encoder := gob.NewEncoder(modelFile) err = encoder.Encode(cls) if err != nil { log.Fatal("保存模型失败:", err) } log.Println("模型已保存到 knn_iris_model.gob") // -------------------------- 新增:模型加载与复用 -------------------------- // 初始化空的KNN分类器用于加载 loadedCls := &knn.KnnClassifier{} // 打开模型文件 loadedFile, err := os.Open("knn_iris_model.gob") if err != nil { log.Fatal("打开模型文件失败:", err) } defer loadedFile.Close() // 反序列化模型 decoder := gob.NewDecoder(loadedFile) err = decoder.Decode(loadedCls) if err != nil { log.Fatal("加载模型失败:", err) } log.Println("模型加载完成,可直接用于预测") // 用加载后的模型预测单行数据 reusePred, err := loadedCls.Predict(predData) if err != nil { log.Fatal("复用模型预测失败:", err) } reusePredLabel := reusePred.Get(0, 0) log.Printf("加载模型后预测类别: %s\n", reusePredLabel)
关键注意点
- 加载模型时,必须初始化与原模型类型完全一致的空实例(如
&knn.KnnClassifier{}),否则反序列化会失败。 - 模型文件会保存所有训练状态,包括KNN的邻居数量、距离计算方式等,加载后无需重新配置参数。
内容的提问来源于stack exchange,提问作者vinniyo
相关产品推荐
相关产品推荐

