大规模机器学习

本文覆盖Coursera Machine Learning Week 10的内容。

大数据集的学习(Learning with large data set)
如果我们回顾过去10年机器学习的发展历史,你会发现现在的学习算法效果比之前要好很多,其中一个重要的原因是现在比以前拥有更多可以供训练的数据。所以有人会说拥有更多的数据比算法更重要:“It's not who has the best algorithm that wins, it's who has the most data.”。所以这篇文章会介绍一些在大数据规模下的机器学习技巧。
先回顾一下之前的梯度下降公式:
$$\theta_{j} := \theta_{j} - \alpha\frac{1}{m}\sum_{i=1}^{m}\left ( h_{\theta}\left ( x^{(i)}\right )- y ^{(i)}\right ) x_{j}^{(i)}$$
上面公式中\(m\)的值可能会很大,比如\(m\)等于一个亿,不要以为这个数据量很大,在实际应用中是很常见的。如果还是按照之前的方法进行梯[......]

继续阅读

数据库定时重置的另一种思路

需求:
网页游戏里面经常会有一些功能模块是需要每天重置的,比如每天有5次抽奖次数,每天可以兑换资源的次数等。那么正常的思路必然是在第二天零点的时候对数据库相关表字段进行update。这是很合理的思维方式,在游戏发展初期是不会有什么问题的。但是当服务器玩家数量增加,零点需要重置的表变多时,0点就会出现很多锁超时的错误:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction导致某些玩家数据库更新失败。那怎么解决呢?

思路:
1.适当地调整MySQL锁超时的时间,默认设置是50S。可以通过设置参数innodb_lock_wait_timeout来调整时间。但是值得注意的是,这个参数不能调得太大,那样的话如果数据库长时间不释放锁会导致程序线程卡死,影响玩家体验。
2.跟策划讨论更改重置时间的可能,把不同的模块尽量错峰执行,比如有些是在0点,有些是在1点,2点等,但这种方式会限制游戏的玩法,不是个好的选择。
3.尽量减少全表更新,比如像这种SQL语句
[crayon-5ae1d5331[......]

继续阅读

服务器接收不到腾讯开放平台的发货回调请求

最近在协助其他组做腾讯平台接入的相关工作,开发蓝钻包月营销活动。虽然两年前我自己的项目已经接入过了,本以为驾轻就熟,没想到还是踩到了一些坑。最大的blocking issue是发货回调地址不生效,也就是发货服务器接收不到腾讯的请求,请求进不来都无法调试了,真是急死人了。最后问题还是解决了,总结下有以下几个原因:
1.平台的缓存问题,但是请注意这个是你最后应该考虑的,因为开平后台发货地址改动的生效时间不会超过5分钟。
2.浏览器缓存
3.前后端API参数是否符合文档要求!仔细核对每一个参数,他们的值,类型等一定要符合官方文档的要求。我们这次接入就是因为一个重要的参数-分区ID:zoneid传错了。前端把这个参数写成了int型,而文档要求的却是字符串类型,从而导致开平后台收不到这个参数,所以没有回调。
4.搞清楚现网环境还是沙箱环境。正常情况下,如果你采用的腾讯云服务器地址是测试地址(119.147.19.43)的话就是沙箱环境,反之就是现网环境。但是有一个例外,就是在测试充值蓝/黄钻会员时,需要修改本机的host使他指向测试地址(这样调试就不用扣真正的Q币了)。在这种模式下虽然服[......]

继续阅读

Can’t attach to the core file

今天在使用jsadebugd调试core文件的时候又报错了:
Error attaching to core file or starting server: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the core file
堆栈如下:

之前碰到这个报错的时候甚至去看了jdk的源码,但还是一无所获。今天灵光一现,通过分析和不断尝试,大致可以总结出有以下几个原因:
1.core文件损坏

2.调试的command不正确,这个工具的使用格式是这样的:

executable必须是java的全路径,而不能是java
所以这样使用是会报错的:

正确的使用方式是:

3.调试用的jdk版本和当时出core的jdk版本[......]

继续阅读

Java位操作符的一种简单应用

几乎每种语言都会有位操作符,左移右移、“与”“非”、“或”、“异或”等,这些操作符的意义大家肯定都知道,但是你可曾想过这些位操作符有什么实际的使用价值吗?今天来说下位操作符的一种简单应用。

在游戏开发工作中最常遇到的是对玩家状态的记录,比如奖励是否已经领取过,页面是否是否打开过等等。如果有连续的状态需要记录则他的形式大致是这样的:0100011,0表示没有,1表示有。最常见的做法是DB里使用一个varchar字段用来存储这样的状态:0100011。每次变更的时候找到那一位的状态,然后改下就好了,很直观。但其实我们也可以使用int类型来存储这种连续的状态,一个整数怎么能表示那么多的状态呢?答案是把十进制整数转换为二进制,然后通过位操作符去变更每一位二进制的状态。

问题:给定一个整数a,我们要改变她所表示的二进制的第n位的值为1。

首先构造一个特殊的二进制数,这个数第n位为1,其余都是0。代码表示就是:

int base= (int)Math.pow(2, n-1);

那如果我要改变第n位的值为1,只要将a|base即可。因为base的第n位是1,而其他位都是0,所以“或”之后第n位只能是1,而其他[......]

继续阅读