问题

实际处理和解决机器学习问题过程中,我们会遇到一些“大数据”问题,比如有上百万条数据,上千上万维特征,此时数据存储已经达到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. cetnos 7 ntp服务的安装与配置

    首先需要搭建yum本地仓库 http://www.cnblogs.com/jw35/p/5967677.html   #搭建yum仓库方法 yum install ntp -y        #安装n ...

  2. Spring注入方式及注解配置

    一:基于xml的DI(Dependency Injection) 注入类型: 定义学生Student实体类和小汽车Car实体类:进行封装和生成ToString(),并自定义属性Car Student ...

  3. 服务器中配置多个Tomcat及内存溢出配置

    1.更改server.xml文件中端口(启动.关闭端口) 2.在startup.bat文件开头加上 SET JAVA_HOME=C:\Program Files (x86)\Java\jdk1.8.0 ...

  4. 使用R语言-RStudio快捷键

    控制台 功能 Windows & Linux Mac 移动鼠标到控制台 Ctrl+2 Ctrl+2 控制台清屏 Ctrl+L Command+L 移动鼠标至第一行 Home Command+L ...

  5. bzoj2523 聪明的学生

    bzoj第一题,ctsc2001. 黑书上的递归例题,我们定义time()函数,递归求解即可. 这个题用到了一个小技巧:可以使用枚举来搞算法. #include <iostream> #i ...

  6. js自定义弹出框

    js自定义弹出框: 代码如下 <html> <head><title>自定义弹出对话框</title> <style type ="te ...

  7. 关于复选框input[type=checkbox]

    关于复选框input[type=checkbox],其实在前面的文章中说过一次,当时主要关注点在设置复选框的状态,利用prop实现,今天继续关注一下复选框. 自己在项目中,遇到一个全选/全不选的需求, ...

  8. 关于swap函数传值的问题

    #include <stdio.h> void swap(int * p3,int * p4); int main() {  int a = 9;  int b = 8;  int * p ...

  9. ACM集训的Day3 B。。。盲目搜索之DFS。。。

    milk 一.题目描述: gzp有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的.有时,农民把牛奶从一个桶倒到 另一个桶中,直到被灌 ...

  10. 基于HTML5和JS实现的切水果游戏

    切水果游戏曾经是一款风靡手机的休闲游戏,今天要介绍的就是一款网页版的切水果游戏, 由JavaSript和HTML5实现,虽然功能和原版的相差太大,但是基本的功能还是具备了,还是模仿的挺逼真,有一定的J ...