CWYAlpha

Just another WordPress.com site

Archive for 一月 2013

Thought this was cool: 如何学习数据科学

leave a comment »

本文翻译自一篇博客文章,作者是一名软件工程师,他描述了在五年时间内学习数据科学的经历和心得,他的学习途径包括了自学(书籍、博客、小项目),课程学习,教学讨论,会议交流和工作实践。

一、入门

1)自学(2 – 4个月)

自学是起步的关键。两年前,我和几个同事组成了一个研究小组,讨论统计202课程的学习材料。这让我感觉很兴奋,并由此开始数据分析的学习研究。研究小组有5名成员,但最后只有2个人选择去更深入地研究这个领域(数据科学并不适合每一个人)。

  • 学习基本的统计知识:统计202课程是非常合适的入门资料
  • 学习一种统计工具:作为一个菜鸟,我用了3个月的时间埋头学习R语言,R学起来非常有趣。(为什么要学习R?
  • 解决一些好玩的小问题:好奇心是数据科学的关键。如果你对国家的经济问题,犯罪统计,体育成绩等感兴趣的话,去收集数据并开始回答你的问题吧。
  • 学习Unix工具:我选择了O’Reilly出版的数据之魅作为学习材料。
  • 学习SQL和脚本语言:我了解的有Java,Ruby和SQL。 Python也在我的名单上。

有很多的培训材料可以在网上找到:

2)课堂训练(9 – 12个月)

如果你想认真提高这项技能,那就选择一门课程,严肃的对待它。斯坦福大学提供了很优秀的课程。

二、聚焦

1)集中所有精力

  • 当我迷上了数据科学时,我发现只花20%的时间是不够的,这需要花100%的时间,所以我会去发现并解决工作中出现的所有和数据相关的问题(大数据分析,医疗保健,零售分析,优化问题)。

2)着手有趣的问题

  • 把学习目标和个人兴趣放在一起。解决有趣的问题,同时学习新的技术是很有用的。例如我对零售,医疗保健和体育数据分析很有兴趣。

3)加速学习:

4)了解业务领域知识
我很幸运,有机会接触到内部和外部的数据科学家,他们帮助我理解他们处理数据问题的方法。我从他们身上学到的“假设驱动的数据分析”,而不是“盲目加蛮力数据分析”的重要性。重点是理解的业务领域问题,然后再尝试从数据中提取有意义的见解。这使我了解一些运营,零售,旅游及物流收入管理和医疗行业。 “纽约时报”近日发表文章,强调有必要为直觉。

3、有用的数据科学读物

4、对我感觉没多大用的东西

  • 学习多个统计工具:一年前,我开始有一些SAS编程的工作要求,我学了一个月左右的SAS,但没什么效果。主要的原因是学习惯性,而且我喜欢用R.我真的没有需要去学习另一种统计工具。R虽然不是完美的,但将R和其他我熟悉的软件工具结合,我可以解决所有数据的科学问题。因此,我的建议是,如果你已经知道了SAS,STATA,MATLAB,SPSS,STATISTICA,非常好,坚持下去。但是,如果你正在学习一种新的统计工具,那就选择R吧。
  • 公开课程:我试图用Coursera来自定进度学习,但对我来说,这不是有效的。我需要有压力,有学分的正式课程。
  • 过多的学习量:需要注意工作与生活的平衡。今年早些时候,我试图同时学习多门困难的课程,我很快就意识到这么干没什么好处。

from 数据科学与R语言: http://xccds1977.blogspot.com/2013/01/blog-post.html

Advertisements

Written by cwyalpha

一月 27, 2013 at 2:53 上午

发表在 Uncategorized

Thought this was cool: Boom – 派生自 foobar2000 的轻量级音乐播放器

leave a comment »

Boom 是款轻量级音乐播放器,单文件版本 2.2MB ,有繁体中文界面。@Appinn

Boom   派生自 foobar2000 的轻量级音乐播放器[图] | 小众软件

感谢 diystar 推荐

Boom 与大名鼎鼎的 foobar2000 来自同一个作者 Peter Pawlowski,其自己对这两款播放器的定义是:

foobar2000
An advanced freeware audio player for Windows
高级音乐播放器
Boom
A simple audio player for Windows.
简单音乐播放器

Boom   派生自 foobar2000 的轻量级音乐播放器[图] | 小众软件 http://perkele.cc/software/boom


©2012 scavin for 小众软件 | 加入我们 | 投稿 | 订阅指南 | 反馈(图片不正常等问题)
b27c41ad47c2611d60d7452a4c02dd52
Boom   派生自 foobar2000 的轻量级音乐播放器[图] | 小众软件
from 小众软件 – Appinn: http://www.appinn.com/boom-audio-player/

Written by cwyalpha

一月 23, 2013 at 3:04 下午

发表在 Uncategorized

Thought this was cool: MEXOpenCV这个能让matlab用opencv的高级货

leave a comment »

东大工科男又发威了,Matlab的出奇的好用是公认的,而且在中国大陆大部分还是不要钱的(嘿嘿),OpenCV相对于matlab是出奇的快,而且在全世界任何的国家都不要钱,而且现在是该有的算法都有了,那怎么结合这两者呢,谁都知道,mex化opencv,但又有谁做了呢?

原东京大学大学院情報理工学系研究科的Kota Yamaguchi(山口光太,是的,我把英文名翻译成了日文名了)童鞋做了这个,现在还是0.1版本,不过支持的opencv函数已经好很多了,

支持的函数列表在:这里

下载在:这里

Tags: ,

from 增强视觉 | 计算机视觉 增强现实: http://www.cvchina.info/2013/01/23/mexopencv/

Written by cwyalpha

一月 23, 2013 at 2:48 下午

发表在 Uncategorized

Thought this was cool: The #NIPS2012 Videos are out

leave a comment »

Videolectures came through earlier than last year. woohoo! Presentations relevant to Nuit Blanche were featured earlier here. Videos for the presentations for the Posner Lectures, Invited Talks and Oral Sessions of the conference are here. Videos for the presentations for the different Workshops are here. Some videos are not available because the presenters have not given their permission to the good folks at Videolectures. If you know any of them, let them know the world is waiting.


from Nuit Blanche: http://nuit-blanche.blogspot.com/2013/01/the-nips2012-videos-are-out.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+blogspot%2FwCeDd+%28Nuit+Blanche%29

Written by cwyalpha

一月 18, 2013 at 7:08 上午

发表在 Uncategorized

Thought this was cool: O(1)?想清楚了没?

leave a comment »

当然标题里这个O(1)可以换成任何复杂度。

话说写程序的时候我们会用到各种数据结构,但十有八九不会由我们自己从头写起,都会直接拿来用。于是很多人就会记住,譬如HashMap或Dictionary的存取是O(1)的操作,二分查找什么的则是O(log(N))。不过,我们在实践中直接把这些类拿来用的时候,最好也留个心眼,知道这些类内部到底做了些什么,为什么它们能够达到O(1)之类的时间复杂度。

例如,我们都知道List<T>的Add是O(1)的操作,但之所以它是O(1),是因为它的“扩容”操作被均摊了(amortized),但每次扩容时其实还是需要复制所有元素,次数越少越好,于是实践中在可行的情况下我们往往应该给它指定一个初始容量——用StringBuilder的时候也是一样。

我这里还可以再举一个更为复杂的例子,例如HashSet和SortedSet,我们要向其中添加N个元素(如字符串),哪个会更快一些?从文档上可以知道,HashSet的Add方法是O(1)的操作,而SortedSet内部是用了红黑树,它的Add方法是O(log(N))的操作(但它能顺序输出元素)。显然,从时间复杂度上来讲,SortedSet的性能要落后于HashSet,不过我们能否设计一个用例,让HashSet慢于SortedSet呢?

当然可以,例如以前那个由哈希碰撞引起的DoS安全漏洞,其实就是设计了一些Hash Code相同,但具体内容不同的字符串,让Dictionary(原理与HashSet相同)Add/Remove操作的时间复杂度从O(1)退化为O(N),这显然低于O(log(N))。不过如今的BCL中的实现已经对碰撞次数设置了阈值,超过这个阈值则会对哈希函数进行随机化,因此这种做法已经很难生效了。所以这里我们可以设计出另一个案例,且看代码:

static string[] GetRandomStrings(int number, int length) {
    var random = new Random(DateTime.Now.Millisecond);
    var array = new string[number];
    var buffer = new char[length];

    for (var i = 0; i < array.Length; i++) {
        for (var j = 0; j < buffer.Length; j++) {
            buffer[j] = (char)(random.Next(Char.MinValue, Char.MaxValue) + 1);
        }

        array[i] = new string(buffer);
    }

    Console.WriteLine("Generated");

    return array;
}

static void CollectGarbage() {
    for (var i = 0; i < 10; i++) {
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

static void AddToSetTime(string name, ISet<string> set, string[] array) {
    CollectGarbage();

    var watch = new Stopwatch();
    watch.Start();

    foreach (var s in array) {
        set.Add(s);
    }

    Console.WriteLine(name + ": " + watch.ElapsedMilliseconds);
}

static void Main() {
    var array = GetRandomStrings(5000, 50000);

    AddToSetTime("HashSet", new HashSet<string>(), array);
    AddToSetTime("SortedSet", new SortedSet<string>(), array);
}

GetRandomStrings方法用于生成一系列的随机字符串,我们会将这些字符串使用AddToSetTime方法放入一个集合类中,并输出耗时。这段程序在我的机器上输出:

Generated
HashSet: 165
SortedSet: 17

您可以自己尝试一下,具体数值可能不同,但HashSet显著慢于SortedSet则基本是确定的。为什么会这样?O(1)为什么完败于O(log(N))?难道HashSet的常数就那么大么?其实原因很简单,我们只需想想HashSet和SortedSet分别是怎么实现的就行。

  • HashSet:调用元素的GetHashCode方法获得Hash Code,算出该元素放在哪个Bucket中,然后顺着链表使用Equals方法依次比较Hash Code的相同元素。由于Hash Code散列程度较高,相同Bucket中重复元素极少,因此时间复杂度近似为O(1)。
  • SortedSet:使用CompareTo方法比较新元素与红黑树里的元素,以此决定元素的树中的“走向”,需要时再进行“平衡”操作。由于一颗平衡二叉树的高度为log(N),因此添加一个元素要进行大约log(N)次比较(以及最多log(N)次O(1)的平衡操作),其时间复杂度大约为O(log(N))。

看起来很正常嘛,但是其中还隐含一些“假设”,那就是GetHashCode、Equals还有CompareTo方法都是O(1)的操作,但事实真是如此吗?针对以上代码生成的随机字符串来说,Equals和CompareTo方法都可以几乎瞬间返回(比较第一个字符即可)。不过GetHashCode便麻烦一些了,便顺手从BCL的代码里摘抄出来吧:

namespace System {

    public sealed class String {

        public override int GetHashCode() {

#if FEATURE_RANDOMIZED_STRING_HASHING
            if (HashHelpers.s_UseRandomizedStringHashing) {
                return InternalMarvin32HashString(this, this.Length, 0);
            }
#endif // FEATURE_RANDOMIZED_STRING_HASHING

            unsafe {
                fixed (char* src = this) {
                    Contract.Assert(src[Length] == '', "src[this.Length] == '\'");
                    Contract.Assert(((int)src) % 4 == 0, "Managed string should start at 4 bytes boundary");

#if WIN32
                    int hash1 = (5381 << 16) + 5381;
#else
                    int hash1 = 5381;
#endif
                    int hash2 = hash1;

#if WIN32
                    // 32 bit machines. 
                    int* pint = (int*)src;
                    int len = Length;
                    while (len > 2) {
                        hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0];
                        hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ pint[1];
                        pint += 2;
                        len -= 4;
                    }

                    if (len > 0) {
                        hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0];
                    }
#else
                    int c;
                    char* s = src;
                    while ((c = s[0]) != 0) {
                        hash1 = ((hash1 << 5) + hash1) ^ c;
                        c = s[1];
                        if (c == 0)
                            break;
                        hash2 = ((hash2 << 5) + hash2) ^ c;
                        s += 2;
                    }
#endif

#if DEBUG
                    // We want to ensure we can change our hash function daily.
                    // This is perfectly fine as long as you don't persist the 
                    // value from GetHashCode to disk or count on String A 
                    // hashing before string B.  Those are bugs in your code.
                    hash1 ^= ThisAssembly.DailyBuildNumber;
#endif

                    return hash1 + (hash2 * 1566083941);
                }
            }
        }
    }
}

从代码里可以看出,撇开最先的InternalMarvin32HashString这个不谈,其他分支下的哈希算法都是与字符串的长度呈线性关系。至于Marvin32这个神秘的哈希算法,我只知道可用于避免哈希碰撞攻击,但搜索了半天都找不到它的具体信息,只有一个“疑似”的简化实现。目前,我们还是用简单的测试来验证字符串长度与GetHashCode方法耗时的关系:

static void GetHashCodeTime(string name, string str, int iteration) {
    CollectGarbage();

    str.GetHashCode(); // warm up

    var watch = new Stopwatch();
    watch.Start();

    for (var i = 0; i < iteration; i++) {
        str.GetHashCode();
    }

    Console.WriteLine(name + ": " + watch.ElapsedMilliseconds);
}

static void Main() {
    var shortStr = new string('a', 100);
    var longStr = new string('a', 10000);

    var iteration = 1000000;

    GetHashCodeTime("Short", shortStr, iteration);
    GetHashCodeTime("Long", longStr, iteration);
}

我们创建了长度相差百倍的字符串,并比较其GetHashCode方法的耗时。我们可以开启随机化的字符串哈希算法(即使用Marvin32哈希算法),例如打开之后在我的机器上执行结果是:

Short: 114
Long: 9142

耗时与长度基本呈线性关系。关闭“随机化哈希”之后执行速度略有提高,但耗时与长度的关系依然不变,其实从代码上也已经能够看出这点。

再回到最早针对HashSet和SortedSet的实验,由于我故意生成了长度高达5w的字符串,因此HashSet时间复杂度为O(1)又如何?单次GetHashCode方法调用的耗时,就已经远远超过许多次CompareTo方法了。从中我们也可以看出,假如我们用字符串作为字典的键,其效率会较int或是普通未重载过GetHashCode和Equals方法的类型为低。话说回来,其实用一个最普通的类作为字典的键效率很高,因为它的GetHashCode可以直接返回它的初始地址,而Equals方法则直接比较两个对象的引用。

在实践中,我遇到各种需要以字符串作为键的场景,我都会思考下有没有简单的替代方法,例如使用int做键,甚至直接使用数组。例如,前段时间@左耳朵耗子提到对一个csv文件里的数据进行排序,我们可以使用一个字典来保存一行数据,其中键为字段名:

List<Dictionary<string, string>> data = ...;
var ordered = data
    .OrderBy(row => row["column0"]) // 先以column0排序
    .ThenBy(row => row["column1"]); // 再以column1排序

但更有效率(内存使用也更紧凑)的做法是以一个数组来保存一行数据。我们先找出需要排序的列的下标,然后再从数组中找出排序用的字段值:

string[] columns = ...;
var index0 = columns.IndexOf("column0");
var index1 = columns.IndexOf("column1");

List<string[]> data = ...;
var ordered = data
    .OrderBy(row => row[index0])
    .ThenBy(row => row[index1]);

从理论上讲,两种做法的时间复杂度一致,但实际上后者比前者会有不少提高。我们在了解“理论”的同时也需要注意实践上的细节,例如,其实在实践中O(log(N))其实也是个不比O(1)大多少的时间复杂度,此时可能也需要考虑下“常数”会对性能造成多大影响。


0

   

0

udpwork.com 聚合
|
评论: 0
|
要! 要! 即刻! Now!

from IT牛人博客聚合网站: http://www.udpwork.com/item/9110.html

Written by cwyalpha

一月 18, 2013 at 6:53 上午

发表在 Uncategorized

Thought this was cool: Y Combinator 2012 Lecture Series – Stanford University – October 20th, 2012

leave a comment »

Written by cwyalpha

一月 18, 2013 at 6:53 上午

发表在 Uncategorized

Thought this was cool: 树莓派入门

leave a comment »

一、树莓派介绍

昨天到货了一台Raspberry Pi B板,从ICKEY上买的(速度还行,三天到货)

512M的RAM,系统从SD卡启动,开关机只需接上或者断开电源即可。

有两个usb口,可以接鼠标和键盘。

支持有线上网。

接显示器的口是HDMI的,要针对自己的显示器接相应的线来进行输出。(其实这根线到了配置好以后就可以省了)

microUSB插口供电,一般手机的充电器(除iphone外)都可以用来做电源使。

操作系统我用的是Debian-Raspbian “wheezy” (点我下载

组装前的图

组装后的图(很小,这是加了个壳子,防止主板裸奔)

二、远程桌面访问和lamp搭建

既然是玩这个东西,我觉得是东西越少越好。

插电后,树莓派的系统就会启动了,所以其实不用给树莓派专门配一个显示器,可以考虑用其他的电脑远程访问。

首先,在pi上安装xrdp,提供远程访问功能。

sudo apt-get install xrdp

pi启动后xrdp会自动运行。

如果你是mac用户,你需要安装一个叫做CoRD的软件。(远程桌面访问软件,点我下载

安装好后连接pi的ip就可以了。

如果你是windows用户,

直接在cmd中运行mstsc.exe打开桌面远程访问,连接pi的ip地址即可。

如果你是linux用户,

apt-get或者yum 安装rdesktop即可。

搭建lamp环境的话,和普通的linux(debian)没什么太大区别,用apt-get安装就可以了。

用mac远程访问pi,搭建了个lamp环境

三、好玩的想法

有的人用pi做web服务器,有的人用很多个乐高和pi做了台超级电脑,有的人拿这个做vpn服务器。

很多想的到想不到的好玩的东西都可以用pi做出来,就因为它是一个非常非常小的pc,用起来非常简单。

推荐几个pi的资源:

(1)树莓派论坛

(2)极客工坊

(3)知乎问答

现在的pi还需要连接电源线和网线以保证实现基本功能,添加一块无线网卡之后,就可以用wifi远程连接pi了;如果能给pi加一个稳定的电源装置,就可以用这个小盒子在anytime,anywhere做一些好玩的事儿了。

from 阿俊的博客: http://somemory.com/myblog/?post=53

Written by cwyalpha

一月 16, 2013 at 11:39 上午

发表在 Uncategorized