本编者为机器学习的广大初学者之一,在机器学习实践此书以及吴恩达老师视频教育下,本人决定将其定期写成笔记(笔记更新进度与速度为学习进度与速度的四分之一),辅助自身学习的同时也来帮助和我一样对machine learning有强烈兴趣并想快速入门的兄弟姐妹们,有勘误的地方欢迎大家斧正。
###本文默认兄弟姐妹们有良好的python基础(做做样子也行),操作系统为windows###
问题
我们都知道在选择一个机器学习模型之后应当有一个测试集对它进行测试,测试集通常是数据集的百分之二十。
在昨天代码的基础下,继续编写一个非常简单的函数(test_radio为取的百分比)
import numpy as np
def split_train_test(data,test_radio):
shuffled_indices = np.random.permutation(len(data))
test_set_size = int(len(data)*test_radio)
test_indices = shuffled_indices[:test_set_size]
train_indices = shuffled_indices[test_set_size:]
return data.iloc[train_indices],data.iloc[test_indices]
train_set,test_set = split_train_test(housing_data,0.2)
print(len(train_set),len(test_set))
运行后出现16512 4128这两个数学就是正确的。
但是这样会出现一个大问题,就是在不断的取百分之20后,数据集的每个值终会取到,这样不是我们所愿。所以我们决定对每个实例设置标识符(本例使用行索引作为ID)
import hashlib
def test_set_check(identifier, test_ratio, hash):
return hash(np.int64(identifer)).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]
housing_with_id = housing.reset_index() #adds an 'index'column
train_set, test_set = split_train_test_by_id(housing_with_id,0.2,"index")
如果使用行索引作为唯一标识符,你需要确保在数据集的末尾添加新数据,并且不会删除任何行。如果不能保证这点,可以尝试使用某个最稳定的特征来创建唯一的标识符。例如一个地区的经纬度:
housing_with_id["id"] = housing["longitude"]*1000 + housing["latitude"]
train_set, test_set = split_train_test_by_id(housing_with_id,0.2,"id")
Scikit-Learn提供了一些函数,可以通过多种方式将数据集分成多个子集。
from sklearn.model_selection import train_test_split
train_set, test_set = train_test_split(housing, test_size=0.2,random_state=42)
分层抽样:将人口划分为均匀的子集,每个子集被称为一层,然后从每层抽取正确的实例数量,以确保测试集和代表了总的人口比例。
创建收入类别属性:
将收入中位数除以1.5(限制收入类别的数量),然后使用ceil进行取整(得到离散类别),然后将所有大于5的类别合并为类别5:
housing["income_cat"] = np.ceil(housing["median_income"]/1.5)
housing["income_cat"].where(housing["income_cat"]<5,5.0, inplace=True)
现在可以根据收入类别进行分层抽样,使用Scikit-Learn的Stratified Shuffle Split类:
from sklearn.model_selection import StratifiedShuffleSplit
split = StratifiedShuffleSplit(n_splits=1,test_size=0.2,random_state=42)
for train_index, test_index in split.split(housing, housing["income_cat"]):
strat_train_set = housing.loc[train_index]
strat_test_set = housing.loc[test_index]
看看所有住房数据根据收入类别的比例分布:
housing["income_cat"].value_counts()/len(housing)
现在可以删除income_cat属性,将数据恢复原样了:
for set in (strat_train_set,strat_test_set):
set.drop(["income_cat"],axis=1,implace=True)
ok,今天完成了测试集创建的过程。下一篇我将详细地带来数据探索和可视化的具体代码来继续入门机器学习知识。磨刀不误砍柴功,4天之内将环境和数据准备好后,我就会和大家一起深入最重要的ml算法阶段。
最后给大家送上一位帅哥的鼓励