[机器学习]Hash以及Hash在选择测试集与训练集中的作用

Hash

hash又被称为散列函数

我的理解,hash是一个过程,也被称为预映射,通过事先设计好的算法,将一个任意长度的字符串,通过这个预映射,得到一个长度固定的输出

这个输出有以下几个特点:

  • 输入值的值域不固定,但是散列值的值域是固定的
  • 对固定的一个输入,有唯一一个输出(称为散列值)
  • 一个输出,可能不止对应一个输入,即不同输入可能指向同一个散列值
  • 一个输入的很微小的变动, 可能会导致散列值的巨大变化
  • 经过hash运算,散列值基本会均匀分布在其值域的各个部分

hash的设计思想

hash的一大作用,就是构造了关键词与其存放的地址(是在hash表中的位置,不是实际的物理地址)的某种关系的映射

如果平时我们要查找数据,可能是遍历一遍数据表,而通过hash表来存储的话,只需输入需要查找的关键词,就能找到对应的数据了(这一点和python中的字典有点像)

可以明显得提升查找的速度

hash碰撞

刚刚说过,不同的输入可能指向同一个散列值,这种情况就成为hash碰撞

常见的处理方法有开放寻址(Open Addressing)法和链接(Chaining)法

具体过程可以自行百度

hash的运用

hash在很多领域都有广泛应用,例如密码学,数据库中存放经过hash运算的密码,就可以防止用户密码被盗(hash运算有不可逆性)

另外就是数据结构,hash表有着较快的查找速度,如果你对速度的要求较高,而且不太重视hash碰撞的话,hash表就比较不错(当然,hash碰撞也有对应的解决方法)

运用hash运算在机器学习中选择测试集

刚刚说到过,hash运算为了充分利用散列值的值域,会将数据尽量均匀地分布在各处

我们可以利用这一特性,将数据的某一特征作为hash运算的关键词,对该特征进行hash运算,然后根据hash运算后的结果,选取一定的比例(通常为20%)作为测试集

这么做的好处
一是可以将数据集打乱,
二是数据集中的训练集和测试集会相对固定,即第二次运行程序时,原本被选为测试集的数据仍为测试集

我们将这种方法与其他方法进行比较:

import numpy as np

def split_train_test(data, test_ratio):
    shuffled_indices = np.random.permutation(len(data))
    test_set_size = int(len(data) * test_ratio)
    test_indices = shuffled_indices[:test_set_size]
    train_indices = shuffled_indices[test_set_size:]
    return data.iloc[train_indices], data.iloc[test_indices]

这个函数的作用是随机选取20%的数据作为测试集

这个做法有效有效但并不完美,因为重新运行时,这个程序会选择不同的测试集,次数多了,你就会获整个数据集

我们可以在程序运行之前这么做,然后保存测试集和训练集,或者,在运行np.random.permutation()之前,给随机数设置随机数种子,np.random.seed(42),这里的42是随意设定的,但是通常我们都用这个

但是,这种方法当数据集变化之后,选择的测试集又会发生变化

所以!!

用hash运算来选择测试集的好处有以下几点:

  • 选择的测试集是固定的,不会因为程序的重启而变化
  • 可以用于不断变化的数据集,即使数据集重新添加了很多数据,运用hash运算不会改变原本的测试集

以下给出的是用hash实现的对数据集的分割

主要思想就是根据数据的序号进行hash运算,计算出每个实例 ID 的哈希值,只保留其最后一个字节,如果该值小于等于 51(约为 256 的 20%),就将其放入测试集

import hashlib

def test_set_check(identifier, test_ratio, hash):
    return hash(np.int64(identifier)).digest()[-1] < 256 * test_ratio

def split_train_test_by_id(data, test_ratio, id_column, hash=hashlib.md5):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio, hash))
    return data.loc[~in_test_set], data.loc[in_test_set]
    
data_with_id = data.reset_index()   # adds an `index` column
train_set, test_set = split_train_test_by_id(data_with_id, 0.2, "index")


本文关于Hash选择测试集的代码取自《hands-on-machine-learning》

欢迎友善的交流与指正

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值