【Kaggle】用随机森林分类算法解决Biologial Response问题

Kaggle搞起来

Kaggle比赛多依靠机器来自动处理,机器学习几乎是必须要的技能。开始搞Kaggle需要的机器学习技能并不深入,只是需要对于机器学习的常见几个方法有基本了解即可,比如说对于一个问题,你可以认识到它是个classification的问题啊还是regression的问题啊,为什么机器可以根据你输入的一个矩阵来算出来分类结果啊。
其实有时候真的在于是不是愿意踏出那一步,一旦踏出了那一步,做与不做真的是天壤之别。
hacker的方式就是通过不断的尝试来学习,所以,搞机器学习,不实践,等于屁事没做。

Biological Response比赛

题目描述

根据分子的化学性质预测生物反应
这个比赛给出了csv格式的数据,每一行对应一个分子,第一列描述了实际的生物反应(分别为类别0和类别1),其余的列是通过分子的特性(比如样本大小、形状和元素构成等)得到的分子描述子,该描述子已经被归一化处理了。

第一次提交

该比赛是一个二元分类问题,其数据经过了特征提取和选择,使得预处理工作更加简单,虽然这个比赛已经结束了,但仍然可以提交解决方案,这样就可以看到你和世界上最好的数据科学家的比较了。
这里,我使用随机森林的算法来进行训练和预测,虽然随机森林是一个比较高级的分类器,但是由于sklearn库,这让该算法的使用变得很简单。
这里我们首先不需要知道这些技术蕴含的数学原理是什么,做实验让我们了解这个算法或工具的工作状况。下面就是运行这个程序,然后将生成的结果提交上Kaggle。

from sklearn.ensemble import RandomForestClassifier
from numpy import genfromtxt, savetxt

def main():
    #create the training & test sets, skipping the header row with [1:]
    dataset = genfromtxt(open('Data/train.csv','r'), delimiter=',', dtype='f8')[1:]    
    target = [x[0] for x in dataset]
    train = [x[1:] for x in dataset]
    test = genfromtxt(open('Data/test.csv','r'), delimiter=',', dtype='f8')[1:]

    #create and train the random forest
    #multi-core CPUs can use: rf = RandomForestClassifier(n_estimators=100, n_jobs=2)
    rf = RandomForestClassifier(n_estimators=100)
    rf.fit(train, target)
    predicted_probs = [[index + 1, x[1]] for index, x in enumerate(rf.predict_proba(test))]

    savetxt('Data/submission.csv', predicted_probs, delimiter=',', fmt='%d,%f', 
            header='MoleculeId,PredictedProbability', comments = '')

if __name__=="__main__":
    main()

评估和交叉检验

如果我们要使用梯度树提升(Gradient Tree Boosting)的方法来代替随机森林算法,或者用更加简单的线性模型。
在这个过程中,从sklearn导入方法并生成提交文件是很简单的,但是如何比较其性能成为了关键问题。如果对模型作了一个调整就提交一次是不实际的。所以我们要依次做两件事:

定义评估函数
交叉检验

你总是需要一些评估函数来决定你的模型执行效果好坏。理想上,这些评估函数最好和Kaggle的评估度量是一样的。在这个问题的比赛中,评估度量是log-loss函数。

import scipy as sp
def llfun(act, pred):
    epsilon = 1e-15
    pred = sp.maximum(epsilon, pred)
    pred = sp.minimum(1-epsilon, pred)
    ll = sum(act*sp.log(pred) + sp.subtract(1,act)*sp.log(sp.subtract(1,pred)))
    ll = ll * -1.0/len(act)
    return ll

最后,我们需要数据来测试我们的模型。当我们第一次提交结果的时候,Kaggle使用log-loss函数比较了你的预测结果和真实世界的结果,没有测试数据的情况下,我们该如何在本地测试我们的模型呢?
交叉验证是一种解决的办法。

交叉检验是一种简单的技术,其使用训练数据的一部分数据进行测试。在sklearn中,它构建了生成交叉验证集的一套工具。
在下面的代码中,构建了10个交叉验证集合,其中将10%的训练数据储备下来,测试算法结果。

from sklearn.ensemble import RandomForestClassifier
from sklearn import cross_validation
import logloss
import numpy as np

def main():
    #read in  data, parse into training and target sets
    dataset = np.genfromtxt(open('Data/train.csv','r'), delimiter=',', dtype='f8')[1:]    
    target = np.array([x[0] for x in dataset])
    train = np.array([x[1:] for x in dataset])

    #In this case we'll use a random forest, but this could be any classifier
    cfr = RandomForestClassifier(n_estimators=100)

    #Simple K-Fold cross validation. 5 folds.
    cv = cross_validation.KFold(len(train), k=5, indices=False)

    #iterate through the training and test cross validation segments and
    #run the classifier on each one, aggregating the results into a list
    results = []
    for traincv, testcv in cv:
        probas = cfr.fit(train[traincv], target[traincv]).predict_proba(train[testcv])
        results.append( logloss.llfun(target[testcv], [x[1] for x in probas]) )

    #print out the mean of the cross-validated results
    print "Results: " + str( np.array(results).mean() )

if __name__=="__main__":
    main()

这里值得一提的是,交叉验证的结果可能和Kaggle给你的打分不一致,这是因为:

随机森林的随机成分会使每次结果不一样;
实际的测试数据有可能偏离训练数据,尤其是数据量小的情况下,训练数据可能无法体现数据分布的整体特征;
验证方式的不同实现也会使得结果有差异

补充:Linux下python科学计算环境的安装

用python进行科学计算主要需要三个包:numpy、scipy、scikit-learn、matplotlib。

安装scipy

可以下载python的包管理工具pip进行安装,但是在安装scipy的过程中遇到一点问题。
Scipy需要LAPACK和BLAS的支持。
这两个数学库是很多linux科学计算软件需要调用的。
LAPACK,其名为Linear Algebra PACKage的缩写,是用Fortran语言编写的用于数值计算的函数集。它提供了丰富的工具函数,可用于诸如解多元线性方程、线性系统方程组的最小平方解、计算特征向量、用于计算矩阵QR分解的Householder转换、以及奇异值分解等问题。
BLAS,全称Basic Linear Algebra Subprograms,即基础线性代数子程序库,里面拥有大量已经编写好的关于线性代数运算的程序。
安装LAPACK和BLAS的过程:

  1. 下载lapack.tgz包,解压到本地
  2. 进入LAPACK文件夹
  3. 将make.inc.example复制为make.inc。该文件为编译配置文件。
  4. 通过make blaslib命令编译BLAS
  5. 通过make lapacklib命令编译LAPACK
  6. 最终得到两个lib文件:librefblas.a和liblapack.a
    补充:这是一个fortran库,需要gfortran的支持,我通过sudo apt-get install gfortran-4.8和sudo apt-get install gfortran来安装fortran的编译器

我在mint系统下,使用sudo apt-get install liblapack-dev也可以很容易的安装,省去了编译的麻烦。
这么试了几次,使用pip install scipy还是有问题,提示是找不到Python.h头文件。
最后找了一个安装scipy最简易的方案,使用sudo apt-get install python-scipy,这样可以一键安装scipy。因为这里会分析软件依赖关系,将需要安装的额外软件包都一并安装,省去了一个一个安装的复杂问题。

安装matplotlib

在linux下安装matplotlib远比在windows中安装要麻烦,我首先下载了源码包进行安装。
使用python setup.py install的时候提示需要freetype和png,于是我使用apt-get安装了libpng-dev和libfreetype6-dev。

出现”error trying to exec ‘cc1plus’: execvp: No such file or directory”问题,解决方案是sudo apt-get install build-essential。

不过最后还是调整了软件源,使用sudo apt-get install python-matplotlib来安装的。安装结束后试验了一下,发现还需要安装python-tk,于是又使用apt-get安装了一下,最终可以正常的使用了。

eclipse开发环境

下载了免安装版的eclipse之后,可以解压到/usr/local/目录中。
然后创建桌面快捷方式,sudo vim /usr/share/applications/eclipse.desktop
属于下面文本:

[Desktop Entry]
Name=Eclipse
Comment=Eclipse SDK
Encoding=UTF-8
Exec=/usr/local/eclipse/eclipse
Icon=/usr/local/eclipse/icon.xpm
Terminal=false
Type=Application
Categories=Application;Development;

将该文件复制到桌面就可以从桌面快捷方式上打开eclipse了。
打开eclipse之后,安装pydev再进行相关配置就可以正常工作了。

转载请注明作者Jason Ding及其出处
GitCafe博客主页(http://jasonding1354.gitcafe.io/)
Github博客主页(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
百度搜索jasonding1354进入我的博客主页

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值