问题

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

    HTML5针对移动端,移动端的浏览器主要是chrome,是webkit内核; app(applicatin):应用; native app:原生的app sadsadsadad 单标签可以省略结尾标记 ...

  2. python字符串

    字符串格式化 字符串格式化使用字符串格式化操作符%来实现:格式化字符串 % 值(字符串或者数字或者多个值的元组,字典) >>> format = "hello, %s. % ...

  3. oracle 取小数位数

    select ltrim('124532.62879'-floor('124532.62879'),'0.') from dual;select length(66695) from dual; 这两 ...

  4. C#自定义控件属性显示在属性面板中操作

    private Color controleColor; [Browsable(true)] [Description("控件颜色"), Category("自定义&qu ...

  5. c#操作mysql积累

    1,连接字符串 Server=localhost;port=;User ID=root;password=admin;database=;charset=utf8;Allow User Variabl ...

  6. *HDU1142 最短路+记忆化dfs

    A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  7. 【emWin】例程二:显示“hello,world”

    实验指导书及代码包下载: http://pan.baidu.com/s/1c1Csx48

  8. win7下wndows virtual pc 2007 装xp比新版本的 Windows virtual pc 好用

    2007下装xp虚拟机启动快,支持拖放.

  9. linux-系统调用

    p { margin-bottom: 0.1in; line-height: 120% } ● Fork() 创建子进程. 创建单个子进程: pid_t pid; pid = fork(); if(p ...

  10. spring <context:component-scan>使用说明(转)

    在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类 ...