问题

实际处理和解决机器学习问题过程中,我们会遇到一些“大数据”问题,比如有上百万条数据,上千上万维特征,此时数据存储已经达到10G这种级别。这种情况下,如果还是直接使用传统的方式肯定行不通,比如当你想把数据load到内存中转成numpy数组,你会发现要么创建不了那么大的numpy矩阵,要么直接加载时报MemeryError。 
在这种情况下我了解了几种选择办法,1. 对数据进行降维,2. 使用流式或类似流式处理,3. 上大机器,高内存的,或者用spark集群。

文档

Sklearn里面提供一些流式处理方法。具体可以参考官方文档: 
讲解了怎么处理 big data 文件:http://scikit-learn.org/stable/modules/scaling_strategies.html 
通过一个例子讲解了怎么用:http://scikit-learn.org/stable/auto_examples/applications/plot_out_of_core_classification.html

简单介绍

我看了上面两个文档,并使用介绍的SGDClassifier进行分类,效果挺好的,这里记录下用法。 
要实现big data的处理,需要满足三个条件: 
1. 有流式数据 
2. 能从数据中可以提取出特征 
3. 增量学习算法

1. 流式数据

第一个条件,要给算法流式数据或小batch的数据,比如一次提供1000条这样。这一块是需要自己写代码提供的,可以实现一个生成器,每调用一次提供一份小batch数据。

2. 提取特征

第二个条件,可以使用任何一种sklearn中支持的特征提取方法。对于一些特殊情况,比如特征需要标准化或者是事先不知道特征值的情况下需要特殊处理。

3. 增量学习算法

对于第三个条件,sklearn中提供了很多增量学习算法。虽然不是所有的算法都可以增量学习,但是学习器提供了 partial_fit的函数的都可以进行增量学习。事实上,使用小batch的数据中进行增量学习(有时候也称为online learning)是这种学习方式的核心,因为它能让任何一段时间内内存中只有少量的数据。 
sklearn提供很多增量学习算法:

  • Classification

    • sklearn.naive_bayes.MultinomialNB
    • sklearn.naive_bayes.BernoulliNB
    • sklearn.linear_model.Perceptron
    • sklearn.linear_model.SGDClassifier
    • sklearn.linear_model.PassiveAggressiveClassifier
  • Regression 
    • sklearn.linear_model.SGDRegressor
    • sklearn.linear_model.PassiveAggressiveRegressor
  • Clustering 
    • sklearn.cluster.MiniBatchKMeans
  • Decomposition / feature Extraction 
    • sklearn.decomposition.MiniBatchDictionaryLearning
    • sklearn.decomposition.IncrementalPCA
    • sklearn.decomposition.LatentDirichletAllocation
    • sklearn.cluster.MiniBatchKMeans

其中对于分类问题,在第一次调用partial_fit时需要通过classes参数指定分类的类别。 
另外有一点需要考虑,所有的学习器在学习过程中不会对每个样例赋予同样的权重。对于感知机,它对于bad样本会敏感,即使学习器已经学习了很多样本了,而对于SGD和PassiveAggressive,对于这种情况会更鲁棒一点,后者在学习的时候,后来学习样本的权重会随着学习器学习率的下降而降低。

实例

这里举一个实际的例子。我这边有上G的训练文件和测试文件,都是csv格式。因为没法直接都读进内存处理,所以选择增量学习的方式处理。

1. 生成一个文件流迭代器

 def iter_minibatches(data_stream, minibatch_size=1000):
'''
迭代器
给定文件流(比如一个大文件),每次输出minibatch_size行,默认选择1k行
将输出转化成numpy输出,返回X, y
'''
X = []
y = []
cur_line_num = 0 csvfile = file(data_stream, 'rb')
reader = csv.reader(csvfile)
for line in reader:
y.append(float(line[0]))
X.append(line[1:]) # 这里要将数据转化成float类型 cur_line_num += 1
if cur_line_num >= minibatch_size:
X, y = np.array(X), np.array(y) # 将数据转成numpy的array类型并返回
yield X, y
X, y = [], []
cur_line_num = 0
csvfile.close() # 生成测试文件
minibatch_test_iterators = iter_minibatches(test_file, minibatch_size=5000)
X_test, y_test = minibatch_test_iterators.next() # 得到一份测试文件

2. 增量训练

 from sklearn.linear_model import SGDClassifier
sgd_clf = SGDClassifier() # SGDClassifier的参数设置可以参考sklearn官网
minibatch_train_iterators = iter_minibatches(data_part_file, minibatch_size=2000) for i, (X_train, y_train) in enumerate(minibatch_train_iterators):
# 使用 partial_fit ,并在第一次调用 partial_fit 的时候指定 classes
sgd_clf.partial_fit(X_train, y_train, classes=np.array([0, 1]))
print("{} time".format(i)) # 当前次数
print("{} score".format(sgd_clf.score(X_test, y_test))) # 在测试集上看效果

3. 结果

0 time
0.679 score
1 time
0.6954 score
2 time
0.712 score
3 time
0.7248 score
...
57 time
0.745 score
58 time
0.7394 score
59 time
0.7398 score

4. 一点补充

  1. 当SGD的损失函数为log时,SGD等价于LR。
  2. 数据只迭代一次分类器可能还没完全收敛,可以多迭代几次
  3. mini-batch的量不要设置太小,太小的话,需要多迭代几次才能收敛

sklearn 增量学习 数据量大的更多相关文章

  1. 关于dedecms数据量大以后生成目录缓慢的问题解决

    四月份的时候博客被封.我不知情.因为一直很忙,没有来得及看.前两天来看以后,发现居然被封,吓傻了我. 赶紧找原因,原来是转载了某个人的博文,被他举报了,然后就被封了. 觉得很伤心,毕竟这个博客陪伴了我 ...

  2. 使用POI导出EXCEL工具类并解决导出数据量大的问题

    POI导出工具类 工作中常常会遇到一些图表需要导出的功能,在这里自己写了一个工具类方便以后使用(使用POI实现). 项目依赖 <dependency> <groupId>org ...

  3. 分布式系统中我们会对一些数据量大的业务进行分拆,分布式系统中唯一主键ID的生成问题

    分布式全局唯一ID生成策略​ https://www.cnblogs.com/vandusty/p/11462585.html 一.背景 分布式系统中我们会对一些数据量大的业务进行分拆,如:用户表,订 ...

  4. DataTable 数据量大时,导致内存溢出的解决方案

    /// <summary> /// 分解数据表 /// </summary> /// <param name="originalTab">需要分 ...

  5. Thinkphp解决phpExcel导出数据量大导致内存溢出

    工作需要导出几万的数据量.操作比较频繁.之前数据在七八千是数据导出很慢.phpExcel是方便但是性能一般.现在改为使用csv导出数据:可以缓解内存压力,一次导出两三万是没问题的.当然服务器内存给力, ...

  6. ASP.NET MVC导出excel(数据量大,非常耗时的,异步导出)

    要在ASP.NET MVC站点上做excel导出功能,但是要导出的excel文件比较大,有几十M,所以导出比较费时,为了不影响对界面的其它操作,我就采用异步的方式,后台开辟一个线程将excel导出到指 ...

  7. MVC学习笔记---MVC导出excel(数据量大,非常耗时的,异步导出)

    要在ASP.NET MVC站点上做excel导出功能,但是要导出的excel文件比较大,有几十M,所以导出比较费时,为了不影响对界面的其它操作,我就采用异步的方式,后台开辟一个线程将excel导出到指 ...

  8. PHP 导出excel 数据量大时

    public function ceshiexcel1(){ set_time_limit(0); $filename = '病毒日志'; header('Content-Type: applicat ...

  9. extjs4 前台导出grid数据 生成excel,数据量大后台无法接收到数据

    最近做的一个web项目使用的是extsj4 框架,需要一个导出excel功能,通过extjs4 自带的导出方法实现.在前台生成excel的代码,form提交传递到后台输出.前台grid数据超过1000 ...

随机推荐

  1. jQuery 利用 parent() parents() 寻找父级 或祖宗元素

    $(this).parent().parent().parent().parent().parent().remove(); //此方法通过parent()一级一级往上找   $(this).pare ...

  2. Linux用户密码重置方法

    方法一: 启动时,随便按一个键,空格即可(不能是回车),让其停留在如下界面 按e编辑 在UTF-8后面添加init=/bin/sh init=/bin/sh 根据上面提示,按Ctrl+x启动得下图 输 ...

  3. zeromq中两个dealer 通过一个router进行通信

    发现有童鞋不是很清楚ZMQ中的“请求-回复”模式中的ROUTER怎么用,所以简单介绍一下“请求-回复”模式的使用(最后付代码). 一.讲一讲 1.要使用zmq 通过一个router进行通信,你首先需要 ...

  4. About_类与对象02

    FCKeditor文本编辑程序(共享软件)为用户提供在线的文档编辑服务,其具有与微软office软件一样的功能,与之不同的是FCKeditor不需要用户安装任何形式的客户端,FCKeditor程序非常 ...

  5. [转]RMAN检测数据库坏块

    backup validate check logical database; select * from v$database_block_corruption; RMAN> backup v ...

  6. php摇杆Tiger摇奖

    先说下整体思路,代码已附下方. 1.递归产生一个非中奖数(即非连续数字:'111','222','333','444','555','666','777','888') 2.点击摇奖,把奖项通过设置的 ...

  7. mysql锁 实战测试代码

    存储引擎 支持的锁定 MyISAM 表级锁 MEMORY 表级锁 InnoDB 行级锁 BDB 页面锁 表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最高,并发度最低.行级锁:开销 ...

  8. 1JavaScript简介

    文档对象模型(DOM,Document Object Model)是针对XML但经过扩展用于HTML的应用程序编程接口(API,Application Programming Interface). ...

  9. server与Portal联合,portal许可过期无法登录。

    server与Portal联合,portal许可过期无法登录,怎样解除联合. 解决方案由峥姐友情提供~~ (1)删除有两种方式(①/②选其一即可): ①类似 链接ttps://sunl.esrichi ...

  10. 将时间转换为xxx天前 xxx..前

    <?php echo (time_fitle('2016-08-17 17:00:00')); function time_fitle($date){ date_default_timezone ...