You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 01:15:39