邓世龙的自留地

兼济天下则达 独善其身则穷

分类目录归档: 学习

教老人使用msconfig.exe


上周日,眼睛疼痛无比,坐着不舒服,站着也不舒服,躺着依然不舒服,于是只好去杭州城走走。

路过老乡的小吃店,于是进去坐坐,因为清明的时间吃了一顿免费的晚餐,还没有感谢他。老乡以前在老家是开食杂店的,来到杭州后开了这家小吃店,一干就是十几年,今年已经62岁了,还在继续干。

聊天的过程中,老人家说,他的电脑开机时,老是会跳出一个飞信登陆框,不知被谁设置的,他想把它去掉。于是我打开启动项,将它设置为开机不启动。老人家看到后,让我教他,并且拿出小本本记下来。

于是我在纸上写下 window + R, msconfig.exe, 点击启动, 之后将需要关闭的服务关掉。可是老人没有学过拼音,于是按照按照字母在键盘上的样子,重新写, 田 + R, MSCONFIG.EXE, 点击启动, 之后将需要关闭的前面的勾勾点掉,之后点确定。于是老人一个字母一个字母的对照,每一个都找的很久,点号更是找不到,于是我告诉他位置。让他重复练习,开机启动,开机不启动,开机启动,开机不启动之后,他终于学会了,很开心的样子。

老人说,手机上很多功能他慢慢都会用,想支付宝啊,微信啊,唯一个麻烦的一些软件设置。他还说,他最担心的就是个人信息被泄露了。之后还很高兴的要加我微信。晚上回到家,他就给我发微信了,关于沙县小吃的。看他的微信,都是一些转发的文章,这次我没有屏蔽他的朋友圈。

于是我有开始思考人生了。想想从三月份以来,自己一直停滞不前,年度计划中的《Java虚拟机》一点都没有动工。我很怀疑等到60岁之后,我能不能像这个老人这样融入社会,对于不满足自己期望的地方,想办法解决,这真是个问题。

正则还是需要认真学的


在我看来,正则表达式也算是一门编程语言的,所以要用好它,还是需要花很长时间,并加上大量的实践。而学习一门语言,必须要知道它的语法规则,正则也有它的规则,所幸这些规则并不多。

许多工程师可能觉得正则只是雕虫小技,需要用到时,上网找个例子就好。可是有些时候,网上的例子并不能解决问题,还是需要自己编写,而正是这些时候,最考验正则水平的时候。如果平时没有积累,在这些问题面前将会束手无策。

而在正则方面,读读《精通正则表达式》就够了,即便是只读前三章,对正则也非一般的了解。作者Jeffery有多年开发经验,并以讲故事的方式讲授正则的知识,正则表达式在他手上娓娓道来。相信读过这本书,对于正则会有登堂入室的感觉。

追踪scws的分词错误问题


分词在搜索引擎当中是极为基础,分词的准确度,对于搜索结果影响很大。可是要写一个分词程序并没有那么容易,一般都是用开源的分词工具,公司使用的分词工具是SCWS。年前,我还不知道这个分词工具是存在一些问题的,直到组长回家之后,产品那边的同事和我说了分词存在问题后,我才注意到这个问题。

例如它会将”情歌接龙大串烧“分成“情歌/n 接/v 龙大/nz 串烧/v“,将”武松杀嫂雕塑是艺术“分成”武松杀/nr 嫂/ng 雕塑/n 是/v 艺术/n“。可是将这两个例子放在命令行中,用scws的命令行工具去分词时,得到的结果竟然是正确的,即它会分成“情歌/n 接龙/n 大/a 串烧/v”,“武松/nr 杀/v 嫂/ng 雕塑/n 是/v 艺术/n”。

刚开始我是一头雾水,根本不知道在哪里错了,比较了之后,才发现在命令行工具中,没有启用rules.ini这个规则表,而在程序中则启用了。于是去查看rules.ini的内容,查看之后,我发现其中只有词性语法规则表对这个分词结果有影响,也就是将v(1) + n = 5这条规则注释掉之后,“情歌接龙大串烧”这个句子分正确了。可是对于“武松杀嫂雕塑是艺术?"这一句,无论怎么修改,都没有办法解决,那么这样只有去修改scws的源码了。

曾一度想放弃修改源码,可是问题无法解决,于是只好去修改它,所幸的是,其关键部分都在scws.c这个文件中,总共也才1000多行,所以还是有希望解决这个问题。对程序所用到的数据结构有所了解后,跟着分词的步骤 一步一步走,有疑问的地方就printf。终于发现问题的症结。问题出在scws.c的885行这里。因为”武“是一个姓,所以它可以做为前缀,而一个姓氏的后面,一般可以跟一到两个字,于是它将"武松杀”合并成一个名字,于是我在885行后面加了个规则判断,如果“武”出现在一个词语的开头,就不用使用前缀规则,修改如下:

if (r1->attr[0] == 'n' && r1->attr[1] == 'r') {//这个是一个姓
    if (wmap[i][i]->flag == SCWS_ZFLAG_WHEAD)//是词的开头,跳过
        continue;

最终解决了这个问题。这里刚开始没考虑周全,后来又出现姓氏在词语中就会出现类似的问题,于是进行了如下修改:

if (r1->attr[0] == 'n' && r1->attr[1] == 'r') {//这个是一个姓
    if (wmap[i][i]->flag == SCWS_ZFLAG_WHEAD || wmap[i][i]->flag == SCWS_ZFLAG_WPART)//是一个词的一部分,跳过
        continue;

}

之后不久产品那边又反应了一个问题。“如果有一张纸写着自己的死亡日期”分成了“如果/c 有/v 一/m 张纸写/nr 着/v 自己/r 的/uj 死亡/v 日期/n",有了上次的修改经验,一看就知道是类似的问题,于是在同样的地方进行了修改,修改如下:

if(r1->attr[0] == 'n'&& r1->attr[1] == 'r' ) { //这个字是个姓氏
    if (wmap[i][i]->flag & SCWS_ZFLAG_WHEAD || wmap[i][i]->flag & SCWS_ZFLAG_WPART) //是一个词的一部分,跳过

        continue;
    if (i > 0) {
        rule_item_t r2 = scws_rule_get(s->r, txt + zmap[i - 1].start, zmap[i - 1].end - zmap[i - 1].start);
        if (r2 != NULL && r2->attr[0] == 'm') //前面是一个量词,跳过
            continue;
    }
}

最终也解决了这个问题。 之后又有一个问题。“一天都坐在办公室”分成了“一 /m 天都 /ns 坐在 /v 办公室 /n”,这里我无能为力了,只好将“天都"从词典中删去。

之后又有一个问题,而这次我无法解决了。”求陈明真的个人介绍“分成了”求 /v 陈明 /nr 真的 /d 个人 /n 介绍 /v“。因为分词的过程中,它会将“陈明真的"这个四个字利用词性语法规则,再加上每个词的权重进行分词,而单从这个四个字来看,“陈明 + 真的"胜出。

在我看了代码后,渐渐理解scws的运作机理,它先将句子中的每个字拿到词典里查询,看看是词的头部还是部分,之后在用一些前缀规则和后缀规则进行处理,之后在用词性语法规则进行分词。而词性语法规则对结果的影响非常明显,修改其中的一些规则,可以令分词错误的句子最后分对了,而同时确又将另一个句子分错了,这注定是一个无底洞,而我不想陷在这里。

这也再一步证明了基于规则的分词方法的缺陷。可是要自己去写一个基于统计的分词方法又不简单,所以还是先用着吧。

金融学笔记--一个实际的问题


两年前就选修过金融学这门课,当时就深深的被Gautam Kaul的哲学所感动。他说,学习这个过程完全取决于学生,只有学生真正想学习了,才能学到东西。而Gautam Kaul非常希望能教每一个人关于金融学的知识,因为在他看来,金融学是如此美妙与充满逻辑。他还说市场是个好东西,它能让好的想法和创意的得到发展的空间,而在这个过程中,将产生价值,给好的想法和创意投出的金钱将得到回报。他说自己多么希望每个人都能在市场中得到回报,可是这不是每个人都能做到的。

现在学习了两周了,学习的过程再次让我找到学生时代的感觉。而课程的知识,也让我知道时间的价值。因为余额包之类的理财产品的出现,存入其中的金钱也得到了相应的回报,随着时间的滚动,金钱慢慢的积累。这时,我才意识到,是应该开始理财了。今天正好有一道实际的题目。

假设你正好30岁,你相信在接下来的20年里可以存一些钱,直到你50岁为止。50岁后直到60岁的10年里,因为孩子的大学费用,结婚等因素的阻碍,你没有办法存钱。如果你想保证自己从61岁开始,每年有10万块钱,在接下来的20年里,平均每年需要存多少钱。假设你的投资回报率为8%,并且你可能活到80岁。

要解决这个问题的第一步,先算出61开始直到80岁,每年的10万块钱在60时值多少钱。

def pv(rate,nper,pmt,fv=0):
     v = pmt * (( 1 + rate) ** nper - 1) / rate / ( (1 + rate) ** nper)
     v += fv / ((1 + rate) ** nper)
     return v

将rate=0.08,nper=20,pmt=10000代入公式,得到981814.74

第二步是将60时的981814.74换算成50时的价值,即 981814.74 / (1.08 ** 10)= 454770.19

之后求出31岁到50这20年,平均每年需要存的钱,用公式

def pmt(rate,nper,pv,fv=0,type=0):
     p = pv * ((1 + rate) ** nper ) * rate / ((1 + rate) ** nper - 1)
     p += fv * rate / ((1 + rate) ** nper - 1)
     return p

将rate=0.08,nper=20,pv=0,fv=454770.19代入pmt(0.08,20,0,454770.19)得到9937.73

而事实上,投资货币基金等风险较低的理财产品,常见的投资回报率为5%,所以重新计算,

  • 第一步:得到1246221.03
  • 第二步,得到765071.60
  • 第三步,得到23137.74

看来为了保证60岁后,每年有10万元的开销,现在可以开始存钱,每年23137.74

Web开发远没有想象中那么简单


以前问过余晟老师,Web开发应该从哪里开始做起,当时余老师回答,先学PHP吧,从一个简单的网站开始做起,前台,后台,功能,设计都走一遍,这样就能 学到很多东西了。可是一直以来都没有动手,临毕业时,因为时间挺多的,于是学着用PHP做一个网站,因为之前有做过欧拉工程的题目,所以打算做一个欧拉工 程的中文翻译网站。真正动手做起来,才知道自己很多都不会。在许多个文件里都有数据库连接的语句,写的乱七八糟的,界面丑陋,不懂设计,不过没关系反正是 自己玩的。

最致命的是我遇到一个问题,那就是在后台输入数据时,内容是放在一个testarea标签里,提交到数据库后,再显示出 来,内容就乱成一团了,原先的段落就没有了。可是去数据库里看,内容还是整整齐齐的分段的,问过同学,一个解决办法是自己在内容里写上标签,然后保存到数 据库,这样从数据库里读出的数据就会带标签的,显示就会正常。这确实可以解决,可是那得多麻烦,我在Wordpress的后台里输数据就不需要这样。最后 毕业了,也没时间去做这个,于是不了了之。

前段时间,志容同学怂恿我去学Django,说用这个开发网站很快,后台基本上不需要自己写。于是又想起以前做欧拉工程中文站的念头,开始做吧。 Django果然强大,如果之前有Web开发经验,看着教程,一步步做,很快就能做好一个网站,主要是它的后台管理做的太好了。可是还是遇到了之前那个内 容乱成一团的问题。问过志容后,说是安装一个富文本编辑器,这样就会将文本转化为HTML,于是照着安装,可是这次是将HTML的源码显示出来,上网查了 之后才知道是经过HTML转义,之需要开启safe就好了。这次显示是正常的,可是确发现从有道云笔记中拷贝过去的文本里,显示出来会多了一些 head,body标签,也就是它将整个文本转化成一个页面了。上网查找不到解决的办法,第二天问志容,他说要看了才知道,问了海峰之后,才知道从网页上 拷贝过去的会显示成一个网页的,要先将文本拷贝到记事本,之后再拷贝到编辑器中就好了。

可是按照这样的方法,结果依然有那些多余的标签,于是我不知道如何做了。

获得机器学习结业证书


之前学习了网络公开课机器学习,很意外的,获得了证书。需要说的是老师Andrew Ag非常好,讲课认真,清晰。课后习题和编程练习的难度很适合像我这样的初学者。以后每年都要在这里选几门课,活到老,学到老。 现在机器学习又开课了,有兴趣的同学可以去听听。