Julia 机器学习 ---- 训练集和测试集的拆分函数

如果只有一个数据集,在机器学习的过程中,一般会将原始数据集分割为训练数据集和测试数据集,训练集 用于训练模型的子集。测试集 - 用于测试训练后模型的子集。但要确保测试集满足以下两个条件:

  • 规模足够大,可产生具有统计意义的结果。
  • 能代表整个数据集。换言之,挑选的测试集的特征应该与训练集的特征相同。

在Julia中也提供了一些拆分数据集的方法,这里给出简单的代码示例。

 

1、流出法

留出法(hold-out)直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T。在S上训练出模型后,用T来评估其测试误差,作为对泛化误差的估计。 需要注意的是,训练/测试集的划分要尽可能保持数据分布的一致性,避免因数据划分过程引入额外的偏差而对最终结果产生影响,常见做法是将大约2/3-4/5的样本用于训练,剩余样本用于测试。

实现方式一:

#为“测试集”和“训练集”,3/4 用于训练,1/4用于测试
using Lathe.preprocess: TrainTestSplit
train, test = TrainTestSplit(df,.75)

实现方式二:

#定义一个布尔变量来将数据拆分为训练集和测试集
train = rand(Bernoulli(0.75), nrow(iris)) .== 1
features = collect(Matrix(iris[:, 1:4]))
#训练数据集
features[train,:]
#测试数据集
features[.!train,:]

实现方式三:

using ScikitLearn
@sk_import model_selection: train_test_split
@sk_import datasets: load_iris

# 加载并返回鸢尾花数据集 (scikit-learn自带的数据集)
iris = load_iris()  # 返回datasets.base.Bunch类型(字典格式)
iris["target"]
# 划分数据集train_test_split() 第一个参数表示特征值,第二个参数表示目标值,test_size表示测试集所占的百分比(推荐0.25)
x_train, x_test, y_train, y_test = train_test_split(iris["data"], iris["target"], test_size=0.25)  # 划分是按比例随机划分
# 返回值 x_train表示训练集的特征值,x_test表示测试集的特征值,y_train表示训练集的目标值,y_test表示测试集的目标值

2、交叉验证法

交叉验证法(cross validation)先将数据集D划分为k个大小相似的互斥子集.每个子集Di都尽可能保持数据分布的一致性,即从D中通过分层采样得到。然后,每次用k-1个子集的并集作为训练集,余下的那个子集作为测试集;这样就可以获得k组训练/测试集,从而可进行k次训练和测试,最终返回的是这k个 测试结果的均值。显然,交叉验证法评估结果的稳定性和保真性在很大程度上取决于k的取值,为强调这一点,通常把交叉验证法成为"k折交叉验证"(k-fold cross validation).k最常用的取值是10,其他常用的k值有5 20等。

   与留出法相似,将数据集D划分为k个子集同样存在多种划分方式。为减小因样本划分不同而引入的偏差,k折交叉验证通常要随机使用不同的划分重复p次,最终的评估结果是这p次k折交叉验证结果的均值,例如常见的有"10次10折交叉验证"

  假定数据集D中包含m个样本,若令k=m,则得到了交叉验证法的一个特例:留一法(Leave One Out).显然,留一法不受随机样本划分方式的影响。因为m个样本只有唯一的方式划分为m个子集(每个子集包含一个样本);留一法中被实际评估的模型与期望评估的用D训练出的模型很相似。因此,留一法的评估结果往往被认为比较准确。然而 留一法也有其缺陷:在数据集比较大时,训练m个模型的计算开销可能时难以忍受的(例如数据集包含1百万个样本,则需要训练1百万个模型),而这还是在未考虑算法调参的情况下。另外,留一法的估计结果也未必永远比其他评估方法准确;“没有免费的午餐”定义对实验评估方法同样使用。

实现方式一:

Julia原生的函数中,MLBase库有一个Kfold函数,可以用于交叉验证,这里给出部分伪代码:

function cross_validation(train,k, learn)
    a = collect(Kfold(size(train)[1], k))
    for i in 1:k
        row = a[i]
        temp_train = train[row,:]
        temp_test = train[setdiff(1:end, row),:]
        #机器学习的函数learn 具体执行逻辑
    end
end

详细的实现可以参考:交叉验证示例

实现方式二:

using ScikitLearn
using PyCall

@sk_import model_selection  : cross_val_score
@sk_import datasets: load_iris
@sk_import svm: SVC

#加载并返回鸢尾花数据集 (scikit-learn自带的数据集)
iris = load_iris()  # 返回
svc = SVC(kernel="linear", C=1)
scores = cross_val_score(svc, iris["data"], iris["target"], cv=5)
# 5-element Array{Float64,1}:
#  0.9666666666666667
#  1.0
#  0.9666666666666667
#  0.9666666666666667
#  1.0

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章