7天晋级机器学习-附加题解析

举报
黑豆梨 发表于 2019/03/12 00:42:01 2019/03/12
【摘要】 这几天报名了华为的【7天晋级机器学习】的培训,其中有一道附加题,本文主要是对这个附加题的解析。

导语

这几天报名了华为的【7天晋级机器学习】的培训,其中有一道附加题,本文主要是对这个附加题的解析。

附加题详见如下链接

https://education.huaweicloud.com:8443/courses/course-v1:HuaweiX+CBUCNXE026+Self-paced/courseware/49179166bcc9439a8d791be91de22176/782a91fffa134a9d9d31b787523dca8b/

数据分析

1、题目采用MAPE作为评分标准 MAPE=abs((target-predict)/target)。

    意味着目标值不能是0的,实际上437个训练数据中,有2个target值为0,这2个是需要剔除的异常值。

    ps: 当然可以不以MAPE作为优化标准,这样就可以不剔除这两个值,但是这样训练出来的结果即使好,MAPE不一定是最优的。

2、在训练数据中目标值target的均值如何呢?约为2.99496568

    可能有同学会问我关心均值做什么?在这个场景中我们完全是捉瞎的,怎么评价我们模型是有效的呢?那首先得有一个标准(例如分类问题我们常采用随机猜,那回归问题该怎么猜呢?)以均值作为我们不采用任何模型时的一个标准,我觉得是一个合理的做法。也就是说我们压根不建模,直接把所有的预测值都置为均值2.99496568,那么MAPE是多少呢?算一下就可以了答案是128.578269%。也就是说我们的模型只要优于这个值,就可以认为是有效的(至少比随机猜好了)。

    ps: 实际上不建模的情况下,以均值来作为预测值并不是最优,可以在方差等方面进一步优化,只是我们毕竟是要建模的,那就先不考虑这个问题了。

数据的拆分

    为了防止过拟合,我们需要对数据进行拆分

    在教科书中,过拟合有很多种解决方法:增大训练集啦,加参数正则项啦,随机丢弃啦等等。

    但是首先一个问题是:如何知道过拟合发生了?一个好方法就是对训练集进行拆分。简单地说,就是把训练其中一部分数据拿出来,作为验证集,不参与训练。等模型训练好后,用模型对验证集进行预测,如果预测结果不错,说明过拟合并不严重。反之,模型在验证集上一塌糊涂,说明很可能是过拟合了。

    ps: 所谓过拟合,就是当我们设计一个足够复杂的模型时,总可以把训练数据拟合得足够好。因为只要参数够多,你总是可以画出一条足够弯曲的曲线来拟合你的数据。但是这种模型对新来的测试数据未必能得到很好的预测。因为的曲线太复杂了很可能已经偏离了数据原本的特性。如果还是很难理解,试想这个场景:我们根据用户的胸围大小和TA的姓氏来预测这个用户的性别,恰巧我们的训练数据中男性都是姓张,那么我们的模型经过训练很可能训练出来【姓张的都是男性】这个结论,而对新来的不是姓张的男性就不能得到准确的分类了。

    下面是一段拆分代码(我们也可以使用华为MLS上的拆分功能来实现)

x_train, x_validate, y_train, y_validate = train_test_split(work_data, work_label, test_size=0.2)

数据预处理

    无论是采用什么模型,为了防止各个输入特征大小差别过大,导致参数调整时各个参数调整的权重不一致,最好先把特征都进行一个预处理,使之符合标准正态分布

    下面是一段预处理代码

mean = work_data.mean(axis=0)
std = work_data.std(axis=0)
x_train = (x_train-mean)/std
x_validate = (x_validate-mean)/std

建模

    这个问题实际上是一个简单的问题:【10维特征向量--->求解1维目标值】

    我尝试了两种模型,1、神经网络(Neural Networks简称NN);2、支持向量机(Support Vector Mechine简称SVM)。因为我也只知道这两种模型了,别的类似Random Forest,贝叶斯网络啊,似乎不太适合这个场景。

1、神经网络(Neural Networks简称NN)

    刚开始的设想是建一个三层的神经网络:第一层是原始的10维输入特征;第二层是隐藏层对10维输入特征进行线性组合构造新特征,同时加激活函数,使得参数可以决定特征能否输出;第三层是一个线性组合输出层对第二层的新特征做线性组合变为1维作为最终的输出。

    我本地用tensorflow进行了实现。

    下面是一段给模型添加一层的代码

def add_layer(inputs, in_size, out_size, dropout, activation_function=None):
    weights = tf.Variable(tf.random_normal(shape=[in_size, out_size], dtype=tf.float64), dtype=tf.float64)
    biases = tf.Variable(tf.zeros(shape=[1, out_size], dtype=tf.float64), dtype=tf.float64)
    Wx_plus_b = tf.matmul(inputs, weights)+biases
    Wx_plus_b = tf.nn.dropout(Wx_plus_b, keep_prob=dropout)
    if activation_function is not None:
        outs = activation_function(Wx_plus_b)
    else:
        outs = Wx_plus_b
    return outs, weights, biases

    下面建立三层网络的代码

    l1, w1, b1 = add_layer(xs, 10, 20, dropout=dropout, activation_function=tf.nn.relu)
    l2, w2, b2 = add_layer(l1, 30, 10, dropout=1, activation_function=tf.nn.relu)
    pred, w3, b3 = add_layer(l2, x_train.shape[1], 1, dropout=1)

    然而最终的效果并不是很好。结果是依赖于前面数据拆分的情况的。不过尽管调整了各种参数,我在验证集上能达到的平均MPAE也仅仅几乎是在48%左右,对比以平均值作为预测值可以看到确实是有效果的。不过这个结果相当于是所有预测值都差不过有48%的误差,实际上并不好。

    ps: 这儿再介绍下我调参时都调了哪些参数

        1、神经个数从5到100都试过

        2、网络的层数2-5层都试过其实2层的情况就是我最终用的普通线性拟合

        3、以哪些w和b来作为正则项防止过拟合。实际上48%的最好结果就是使用全部w和b得到的。

        4、使用dropout随机丢弃来防止过拟合结果并不是很好。

2、支持向量机(Support Vector Mechine简称SVM)

当时对SVM是寄予厚望的。毕竟传说中SVM在小数据集上的表现往往优于神经网络,实际上我担心的反而是过拟合问题。然而最终的效果也不是很好,尽管调了各种参数,我在验证集上能达到的平均MPAE也仅仅几乎是在56%左右。

主要代码如下

	svr = SVR(kernel='rbf')
	svr.fit(x_train, y_train)
	y_predict = svr.predict(x_test)

ps: 在SVM中主要是调整了所用的核函数,linear、poly、rbf、sigmoid都试过了,几乎没有什么区别。别的还有很多参数没有细调,估计好好调也许也能达到神经网络的效果。

3、因为NN和SVM在我这儿都没有取到很好的效果,于是我想回到最简单地做法,如果就认为

    target = w1*f1 + w2*f2 + ... + w10*f10  

    就做这么个模型,结果如何?实际上这个做法就是把NN中第2层去掉。

    跑了下,大概能得到46%的MAPE。同时我也注意到,使用这个模型的时候,我的训练集和验证集往往MAPE差别不大,几乎都是在46%左右。这就意味着我们的模型其实在训练集和验证集上表现都不好,但不会过拟合。所以最后的模型,我是干脆去掉了验证集,直接用所有训练数据来训练这个线性模型

ps: 实际上仔细看NN和SVM的输出结果,会发现他们的预测值该大的大,该小的小。反而是普通的线性拟合结果四平八稳,也就是说每个值我都不好,但是也不会太差,就是差个46%左右。

    所以我觉得如果继续增大训练集,也许NN和SVM的表现会好吧。

    另外这个现象应该也是选取MAPE作为评估导致的结果,选用MAPE就是偏向这种四平八稳的预测结果的。

完整代码可在附件中下载


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。