东哥IT笔记 Blog

0

十个最佳数据科学相关的Python库

我们都知道Python很流行也很易学, 本文将列出十个最佳的数据科学相关的Python库。希望对你能有所帮助。 NumPy NumPy十个主要用于数据分析,科学计算以及数据科学的库。NumPy支持多维的数组和矩阵。他是数据科学中的最基础的库之一。NumPy也被TensorFlow内部使用,并且被很多别的库所使用。很多时候,NumPy更像一个同样的Python库一样。 Pandas Pandas是另外一个Python库,它专精于数据的整理和合并。它可以方便快捷来进行数据的整理,合并和数据图形化显示。Pandas常被用来从一个CSV文件中创建数据框架。 Matplotlib Matplotlib在数据可视化中非常有用。它提供了很多种有效显示数据的方法。你可以使用它来很快速地画出曲线图,饼图,直方图以及各种各样的专业图形。你可以自定义图表中的任何部分。 Scikit-Learn Scikit-Learn是针对经典的ML算法的最动态和广泛的库之一。它是基于两个库来实现的,一个就是我们上文提到的NumPy,另外一个Scipy。它可以为大多数监督和非监督算法提供支持。这个库也可以用于数据挖掘,数据收集以及数据分析,所以它对很多ML的初学者来说也很有用。 TensorFlow TensorFlow不需要多说吧,他是一个用于机器学习应用的库,你可以实现神经网络等等各种算法。它是目前为止最流行的机器学习的库,虽然不是第一个,但自从它出现后,很快就迅速超过了所有其他的库。 Keras Keras是一个强大的Python机器学习库。它是一个高级的神经网络API,可以运行在TensorFlow,CNTK或者Theano之上。它可以独立地在GPU或者CPU上运行。对于新手来说,使用Keras非常方便和快捷。 Scrapy Scrapy是一个用于进行网络抓取的Python框架。它主要用于提取,保存和处理大量的网络数据。我们可以使用它来很方便地处理大量的数据。 Seaborn Seaborn其实是基于Matplotlib创建一个数据可视化的库。你可以使用它来整理信息性和统计性的视觉效果以及说明性图表。Seaborn是的数据可视化成为数据探索和分析不可或缺的一部分。它这个库非常适合测试多个变量之间的关系。 SciPy SciPy是一个包含各种线性代数,数学计算,优化和统计模块的库。开发者可以使用它来进行傅里叶变换,ODE求解,信号和图像处理等。 Plotly Plotly是一个开源的绘图库,它支持超过40中图形类型,基本涵盖了所有的分析,经济,地理,科学和三维用例等等各个方面。 总结 总得来说,了解上面十个Python库是你学习数据分析的重要武器,希望你们能够喜欢。

0

ShaZam深入分析之从数字声音到频率

我们在之前的文章中介绍了如何从模拟声音转变到数字声音。现在假如有了一个数字声音,你如何得到他的频率呢?这个部分很重要,因为ShaZam的算法基本都是基于频率的。 对模拟信号来说,这里有一个变化称为连续傅里叶变换。它可以把一个时间的函数转变成频率的函数。也就是假如把傅里叶变换应用到一个声音上,你就会得到它的频率。 但是这里有两个问题: 我们处理的数字信号,所以它是一个有限的不连续声音。 为了更好地理解音乐内部的频率,我们需要把傅里叶变换应用到整个音乐信号的更好的部分,比如我们需要把它应用到0.1s的部分。 还好,我们这里有一个新的数学函数,称之为离散傅里叶变换。 离散傅里叶变换 DFT(离散傅里叶变换)应用到离散信号中,并且返回一个离散的光谱。下面这里是它的公式: 这个公式中: N是窗口的大小:组成信号的样本数目 X(n)代表第n个频率区间 x(k)是音频信号中的第k个样本 例如,对一个有4096个样本的音频信号,我们需要应用这个公式4096次: n=0计算第0个频率区间 n=1计算第一个频率区间 n=2计算第二频率区间 你也许注意到,我说的是频率区间而不是频率。这是因为DFT给出的离散光谱。频率区间是DFT能够计算的最小频率单元。频率区间的大小等于信号的采样率除以窗口的大小(N)。在我们上面的例子中,有4096个窗口,标准的声音采样率是44.1kHz,所以频率分辨率就是10.77Hz (第0个有点特殊) 第0个频率区间是0Hz到5.38Hz 第一个频率区间是5.38Hz到16.15Hz 第二个频率区间是16.15Hz到26.92Hz 第三个频率区间是26.92Hz到37.68Hz 这就意味着DFT不能够区分小于10.77Hz的两个频率。比如27Hz,32Hz,37Hz其实都落在同一个频谱区间。假如37Hz的音符比较重,你只会知道第三个频率区间比较重。这个对最低八度音阶的解离其实是有问题的,比如: A1在55Hz,而B1在58.27Hz以及G1在49Hz。 标准88键的第一个音符实在A0 27.5Hz,然后后面是A#0位于29.14Hz 你可以通过增加窗口大小来改进频率分辨率,但这也意味着会丢失音乐中的快速频率/音符的改变: 一个音乐信号的采样率是44.1 kHz 增加窗口的大小意味着增加更多的样本,因此就是增加window的时间。 对于4096样本,这个window的时间就是0.1秒,频率分辨率是10.7Hz:你可以每0.1s探测一次改变 对于16384样本,这个window的时间就是0.37s,频率分辨率就是2.7Hz:你只能探测到0.37s的改变。 音频信号的一个特殊性就是只需要通过DFT计算一般的频率区间。在之前的定义中,频率区间的定义是10.7Hz,这也就意味着2047个的频率区间展现了从21902.9Hz到21913.6Hz。但是: 第2048个频率区间和第0个是一样的...

0

ShaZam深入分析之音乐数字化

除非你是发烧友,否则一般来说我们听的音乐都是数字文件,比如mp3等等。但事实上,制作音乐的时候,都是模拟的。音乐其实最终都是数字化以便于用电子设备进行存储和播放。那么本文就来讲讲如何从模拟转变成数字,了解了这些之后,会有助于我们后面的理解 采样 模拟信号其实是连续的信号,这也就意味着你可以把一秒的模拟信号分成无数份。而对数字信号来说,你不可能保存无限的数据。所以,你需要一个最小的单元,比如1毫秒。在这个单元里面,声音是不变的,所以为了能够足够接近模拟信息,这个单元需要足够小,但有不能太小,否则就需要很大的空间来存储这个数字信息。 我们可以想象一下,哪怕是你最喜欢的音乐,但是每两秒的声音都不变,这听起来估计也很奇怪。所以为了你的音乐听起来很好,你可以选择一个很小的单元,比如一个纳秒等,这时你的音乐听起来就非常赞,当然你可能没有足够的磁盘来保存这种音乐。 所以,这时候就需要使用本节的主题:采样。 标准的数字音乐是44100单元每秒,我们称之为采样率。我们在前文中提到,人耳能听到的声音范围是20Hz到20kHz。Nyquist和Shannon定理指出假如你想要数字化一个信号到0Hz到20kHz,那么你需要最少40000的采样率。主要的思想是一个F频率的正弦波需要至少每个cycle 2个点来鉴别。我们来看下面这个图: 上图中,20Hz的声音被40Hz的采样率来进行数字采样。 蓝色的波形是20Hz的声音 红色的叉就是声音的采样,也就是说每1/40秒采样一次。 绿色的线是采样声音的插值 虽然这个形状和振幅不同,但是采样信号的频率是一样的。 下面是一个坏的采样例子: 这张图中,20Hz的声音是30Hz的采样率。这个采样信号的频率和原来的信号的频率是不同的:它的频率只剩10Hz了。假如仔细看看,你会发现采样中的一个cycle是原来信号中的两个cycle。这就是采样不足的情况。 这个例子还说明一个问题:假如你想要数字化一个在0Hz到20KHz之间的信号,那么你需要先把超过20kHz的频率去除。否则这些频率会被转到0Hz到20KHz之间的信号,从而产生我们想不到的干扰。 总的来说,假如你想把一个音乐从模拟转变成数字信号,那么采样率最好40000次每秒。 量化 我们看到如何数字化频率,但是声音的大小怎么办呢?声音的大小是相对的,同样的信号,假如你把扬声器的声音调大,声音也会变大。所以响度是一首歌中最低和最高声音之间的变化。 所以这里有了一个问题,怎么把这些信息从连续的模拟信号转变成离散的量。 我们来假设你最喜欢的音乐有四个响度:没有声音,低声,高声以及最高声。当然现实不是这样的,但我们这里只是做一个例子: 下面就是这个例子的图片: 这张图显示了8个级别的量化,你可以看到声音的结果(红色)产生了很大的变化。真实声音和量化的线之间的差别我们称之为量化错误或者量化噪音。8个级别的量化我们也称为3bit量化,因为你需要3个bit来表示八个不同的级别。 下面是一个64级别的例子(6bit) 这张图中可以看出,虽然结果看起来还是有点差别,但是和原来的声音已经更加接近了。 还好人耳的声音辨识度不是太高,所以标准的量化值是16bit,也就是说65536级。也就是16bit的量化值对人耳来说已经足够低到无法分辨了。 脉冲编码调制 脉冲编码调制就是我们通常说的PCM,它是一个显示数字信号的标准。很多电子设备都使用它,比如你听mp3的时候,mp3其实会自动转换成PCM信号,然后再发送到你的耳机。 一个PCM流就是一个有组织的bit信号。它可以有多个通道,比如,立体音就需要2个通道。 在一个流中,信号的振幅被分成sample。每秒的采样数目和音乐的采样率有关。比如44.1KHz的音乐就是每秒采样44100 sample。 有很多PCM的格式,最常使用的是PCM 44.1KHz,16 bit深的立体音。这个格式每秒有44100的采样点。每个采样点有4 byte:...

0

ShaZam深入分析之音乐基础

我们都知道声音是通过空气(或水等介质)进行传播的振动,然后由人的耳朵进行解析的。比如我们听音乐,声音就是通过空气传播,然后被你的耳朵所接受。光也和声音类似,只是说这次你的耳朵没法解析它,但是你的眼睛可以。本文就来介绍一下,音乐是如何用物理、技术进行描述的。 纯音和真实的声音 所谓的纯音就是正弦波形的音。正弦波有下面这些特性: 它的频率: 每秒的循环数,它的单位是赫兹(HZ),比如100Hz = 100循环/s 它的振幅(声音的大小相关):每一个循环的大小 人耳就是通过解析这些特性来组成声音的。人耳可以听到20 Hz 到 20000Hz的声音,而随着岁数的增加,这个范围不断地在缩小。 人耳对响度的感知取决于纯音的频率,比如一个30Hz的(振幅10)纯音听起来比100Hz(振幅10)的要轻。人耳遵循心理声学模型,具体你可以参考这边文章。 上图显示的就是一个纯音的波形,它的频率是20Hz,振幅是1. 纯音在自然界并不存在,但是任何声音其实都可以看成是多个不同振幅纯音的组合。 上面这幅图,你可以看成它是由多个正弦波组成的: 一个20Hz,振幅1的正弦波 一个40Hz,振幅2的正弦波 一个80Hz,振幅1.5的正弦波 一个160Hz,振幅1的正弦波。 现实世界中的声音可能由成百上千个纯音组成。 音符 音乐其实是由一系列音符组成的,这些音符也有长短和大小。 音符可以分成八度,也就是我们常说的A,B,C,D,E,F,G或者Do,Re,Mi,Fa,Sol,La,Si。而且它们有下面这些特性: 音符的频率是上一个八度的两倍,比如说A4的(A在第四度)的频率是440Hz,它就是A3的频率(220Hz)的两倍,是A2(110Hz)的四倍。 很多乐器以八度为单位提供了高于八个音符,我们称之为半音。 对第四度音来说,这些音符的频率如下: C4(Do3) = 261.63Hz D4(Re3) = 293.67Hz E4(Mi2)...

0

最好的编程语言

我们经常会听到有人说,PHP是最好的语言,也有人会说Java才是最好的语言,很多时候这些讨论文章的唯一目的就是让我能笑一笑,其实我们大家都知道,哪有什么最好的语言,各种语言都有其擅长和不足的地方,那么在我们实际工作中,如何来选择一个最好的语言呢? 是否有性能要求 假如你有明确的性能要求,那么我们就需要来具体分析了: 秒级:任何语言都可以做到 毫秒级:任何语言,只要程序员本身过关也都可以做到 微秒级:这个量级,很多解释性语言就可以排除了(比如Python,当然它本身很好),一个很好地程序员使用JVM是可以达到这个量级的,同样的,我想C#应该也是可以做到的。当然,纯编译语言也是可以做到的。 纳秒级:大概只有汇编或者C能够做到了。 生态系统是怎样的 其实除了语言本身,它的生态系统也很重要。比如说我们使用Visual Studio,然后你会发现很多人使用它,它的生态系统很赞。相应的工具很重要,比如Eclipse,VsCode,他们都有很多各种各样的插件可以使用,这样一来,相关语言的开发就会省力很多。 线上帮助 我们都知道,哪怕你对一个语言再熟悉,也有不懂得地方,这个时候就需要去Google或者StackOverflow上进行查询和提问,这个时候,一个热门的语言会有很多人遇到类似的问题,这无疑对你的工作是有所帮助的。 团队成员的技能 很多时候,我们要使用的不是一个最好的,而是一个大家都熟悉的,尤其是使用团队成员了解并喜爱的语言可以极大地提升工作效率和激情。 商业方面的考虑 一个很现实的问题,就是你可能会选择一个需求量最大的语言,而不是最好的语言。毕竟这样一来,至少你换工作的时候能够有所帮助。从另一个方面来说,假如你是一个tech leader,你选择了一个“最好的”语言,但是没什么人会,你想招一个有相关经验的人可能都招不到。 不过总得来说,没有什么最好的语言,只有最合适的语言。归根结底,语言只是我们的工具,我们的目标是解决问题,针对问题来进行选择,也许这才是正确的做法。

如何通过基于OAuth的API连接Vue.js 0

如何通过基于OAuth的API连接Vue.js

很多人都使用过基于OAuth的API,比如你在一些网站使用GitHub登录的时候,你就使用GitHub提高的OAuth2 API,或者你使用Google或者Facebook登录的时候,你也会使用到它。 现在OAuth真的无处不在,也许因为它真的非常好,用户只要点一个按钮,然后得到权限,这样就可以了。 但是当我们进行开发它的时候,就是另外 一个故事了,也许是因为它一次性引入了太多的新的内容。本文我们会介绍一个小的工具Bearer.sh Pizzly,有了它之后开发OAuth就方便多了。 首先来看看它长什么样子: 下面我们来看看如何使用它。 Vue.js skeleton 为了学习如何使用基于OAuth的API,我们首先需要一个Vue.js skeleton,或者至少需要一个能使用OAuth2 API的应用。 假如你已经有了GitHub的账户,我们可以使用它的API,当然别的基于OAuth的API也是可以的。 GitHub API提供了一个端口(/user/starred)列出了用户的所有的repositories。这个端口是需要authentication的,所以听起来是一个很好的使用场景。 下面是一个简单的应用代码: 这个应用代码是一个很简单的Vue.js,假如user变量已经设置了,就会显示repositories的内容个,否则就要求用户连接GitHub。 认证的部分 我们使用开源的Pizzly,它使用了.connect的方法来从前端触发认证。我们来看看如何在上面代码中加入这个内容: 是不是很简单,只要几行代码就完成了。 配置部分 在上面的代码中有一个最重要的部分就是Pizzly的初始化,这里就要提到Pizzly其实需要一个Oauth Manager,也就是说你需要把它托管在某一个地方,比如Heroku等。当这个托管完成之后,你就可以使用Pizzly的仪表板了,这也是你配置你的GitHub的地方: 总结 这样你就可以在Vue.js中使用任何基于OAuth的API了,关于任何Pizzly的意见,欢迎大家提出。 参考文章:https://hackernoon.com/connecting-vuejs-with-oauth-based-api-ks1v3ucj

0

关系型数据库进阶之Log Manager

我们在之前的文章中聊到,数据库为了提高它的性能,会把数据存在memory buffer中。但是这里有一个问题,就是假如一个已经committed的transaction crash掉了,你因为这个crash丢掉了memory中的数据,那就会出现了Durability的问题。当然你也可以把所有的数据都写到磁盘中,但是同样的问题,假如写到一半就crash了,这里就会发生原子性的问题。 所以这里的我们的原则是任何通过transaction进行写的修改都要么是全部完成要么就是什么都不做。 为了解决这个问题,有两个方法: Shadow copies/pages: 每一个transaction都创建它自己的数据库(或者部分数据库)备份,然后在这个备份上进行操作。假如有错误,这个备份就移除掉。假如成功了,就切换到这个备份上,而把旧的备份删除掉。 Transaction log:transaction log是一个存储空间。在把数据写到磁盘之前,数据库把相关的信息写到transaction info中,因此即使有crash或者cancel的时候,数据库也知道怎么来完成或者移除响应的没有完成的transaction。 WAL Shadow copies/pages的思想其实很好,唯一的问题就是在大的数据库中,会额外浪费很多磁盘的空间。这也是为什么现在主流的数据库都是用transaction log来解决这个问题。Transaction log必须存储在一个稳定的存储空间中。 大多数数据库(至少Oracle, SQL Server,DB2, PostgreSQL, MySQL以及SQLite)都使用Write-Ahead Logging protocol (WAL)来处理transaction log。这个protocol主要有三个规则: 每一个对数据库的修改都产生一个log记录,并且log记录必须在数据写到磁盘前写到transaction log中。 log记录必须按照顺序写,也就是说发生在记录A先发生,那么记录A就必须先写。 当一个transaction committed了,这个commit的顺序必须在transaction介绍前写到transaction log中 这些工作都是在log manager中处理的,他位于cache...

0

关系型数据库进阶之Transaction manager

在前面的文章中,我们介绍了查询管理,查询优化以及数据管理,本文就来继续介绍Transaction manager相关的内容。它主要是用来保证每一个query都在它自己的transaction中执行。不过在此之前,我们需要理解一下ACID transaction。 ACID ACID transaction是一个工作单元,它主要包含4个方面: 原子性:transaction是“要么完成所有,要么什么也不做”,哪怕这个操作需要10个小时来执行。假如transaction crash,那么所有的state都需要roll back到之前的状态。 隔离性:假如有两个transactionA和B一起执行,不管A是在transactionB之前还是中间还是之后完成,结果都是一样。 耐用性:当transaction committed(成功完成),不管发生什么数据都会保存到数据库。 一致性:只有有效的数据才会写到数据库,一致性是和原子性以及隔离性相关。 在同一个transaction中,你可以运行多个SQL query来读,创建,更新和删除数据。但是当她们使用同样的数据的时候,就会造成混乱。我们来看下面这个例子: Transaction 1 从account A中取出100块钱,并存到account B中 Transaction 1 从account A中取出50块钱,并存到account B中。 我们来从这个例子中看看ACID中各个属性: 原子性:不管发生什么,你都不能从account A中取出100块钱,而不存到account B中去。 隔离性:需要确保假如T1, T2同时发生,最终account A被取出150块并且account B收入150块。而不会发生别的,比如account B只收入50块之类的。...

0

关系型数据库进阶之数据管理

我们在前面已经介绍了客户端管理,查询管理,今天来介绍数据管理。 在这一步中,查询管理会执行相应的查询,这个时候就需要从表和index中得到数据了。它需要数据管理来获取数据,不过这里有两个问题: 关系型数据库使用的是transaction的模式,所以你不能够在任何时候都得到数据,因为同时可能有别人在使用或者修改数据。 数据的获取是数据库中所有操作最慢的操作,所以数据管理需要足够聪明,来把数据保存在内存buffer中。 本文我们就会来讨论关系型数据库是如何处理这两个问题的。 Cache管理 就像我们前面几篇文章提到的一样,数据库的瓶颈就在于磁盘I/O,所以为了改进性能,需要使用cache管理器。 Query的执行器并不是从文件系统直接获取数据,而是通过cache manager来请求数据。Cache manager有一个memory的cache,我们称之为buffer pool。显然动态地从cache请求数据会增加数据获取的速度。一般来说memory相比磁盘来说会快100到100K倍,当然这还取决于决定的硬件和读写方式。 但是这里就会有另外一个问题,就是cache manager需要在query执行之前就获取到相应的数据,否则就还需要访问磁盘来数据。 预获取 query执行器其实是知道它所需要的数据,因为它知道整个query的所有流程。基于此,我们可以让query执行器处理第一部分数据的时候,就要去cache manager去预加载第二部分的数据,然后当它处理第二部分的数据的时候,就让cache manager去预加载第三部分的数据,这样循环下去。 Cache manager会把所有的数据保存在它的buffer pool中,为了检查相关数据是否还需要,cache manager在所有的cache数据中加入了一个额外的信息(我们称之为latch)。 当然有时候query执行器也不知道它下面要什么数据,这个时候就会使用一些特殊的预加载(比如,query执行器要数据1,3,5,那么它很有可能在未来需要数据7,9,11)或者顺序获取(这种情况下,cache manager就继续加载磁盘中后面的数据)。 为了探测预获取的效率,数据库提供一个称之为buffer/cache hit ratio的指标,这个指标会显示当请求一个数据的时候,有多少次是可以直接在cache中获取而不需要访问磁盘。 但是另外一个问题就是memory的大小毕竟有效,所以假如要加载新的数据,那么就得去除一些旧的数据,而这些加载和去除都是需要磁盘以及网络I/O消耗的。假如有一个查询经常执行,那么我们就会频繁地加载和去除相关的数据,这显然是不太合理的,那该如何处理呢?现代的数据库使用一种称之为buffer替换的策略。 buffer替换策略 现代的数据库(至少SQL Server, MySQL, Oracle和DB2)基本都使用LRU算法。 LRU就是Least Recently...

0

关系型数据库进阶之查询优化二

在前面的文章中我们介绍了查询优化的基础,着重介绍的两个表的JOIN的优化。本文就来看看我们在实际中更常见到的多表JOIN的优化。 现在我们来假设有五个表进行join,我们需要从不同的表中得到一个人的不同信息,比如地址,mail,mobiles等等,简单的QUERY如下所示: 作为查询优化器需要找到最佳的查询数据的方法,这里有两个问题: 每一个join需要使用什么类型的JOIN?我们有三种可能的JOIN (Hash Join,merge  Join, Nested Join) 先做哪个JOIN再做哪个JOIN? 下面这个是一个简单的示意图,有四个表,三个JOIN的情况,显然五个表的情况会更加复杂。 好的,那我们该怎么做呢? 1)暴力解法 遍历所有的可能性,然后找到最佳的方法。在上面的例子中,每一种join有三个可能(HASH, MERGE, NESTED),对于给定顺序的JOIN就有3^4中可能,而JOIN的顺序也是不定的,四个JOIN其实有(2*4)!/(4+1)!种可能的排序,这样一来,这个五个表的JOIN有 3^4*(2*4)!/(4+1)!种可能。 也就意味着,有27216中可能的计划。假如说merge join有0,1,2 B+ tree index,那么这种可能性就变成210000种了。而这还只是一个简单的JOIN。 2)只试验一些计划,然后选择其中最好的 因为可能性太多了,那么我们随机选择其中一些,然后计算他们的cost,选择其中最好的。 3)应用一些规则,来减少可能的计划 这里通常有两种规则: 使用一些简单的逻辑规则去除一些没有用的可能性,只是说这种去除不是很多。比如“nested loop join的inner relation必须是最小的数据集“ 使用一些有侵略性的规则来减少可能性。比如“假如一个relation很小,那么使用nested loop而不使用merge join和hash join”...