技术

Python实践 下一个平台Agent 激发LLM涌现——提示工程 LLM微调理论及实践 大佬沉思 LLM外挂知识库 LLMOps 多模态LLM Python一些比较有意思的库 LLM部分技术源码学习 LangChain源码学习 通用分布式计算引擎Ray Python并发 go依赖注入 go collection gc的基本原理 golang性能分析及优化 数据湖 高性能计算与存储 Linux2.1.13网络源代码学习 《大数据经典论文解读》 三驾马车学习 Spark 内存管理及调优 Yarn学习 从Spark部署模式开始讲源码分析 容器狂占内存资源怎么办? 多角度理解一致性 golang io使用及优化模式 Flink学习 c++学习 学习ebpf go设计哲学 ceph学习 学习mesh kvm虚拟化 学习MQ go编译器以及defer实现 学习go 为什么要有堆栈 汇编语言 计算机组成原理 运行时和库 Prometheus client mysql 事务 mysql 事务的隔离级别 mysql 索引 坏味道 学习分布式 学习网络 学习Linux go堆内存分配 golang 系统调用与阻塞处理 Goroutine 调度过程 重新认识cpu mosn有的没的 负载均衡泛谈 单元测试的新解读 《Redis核心技术与实现》笔记 《Prometheus监控实战》笔记 Prometheus 告警学习 calico源码分析 对容器云平台的理解 Prometheus 源码分析 并发的成本 基础设施优化 hashicorp raft源码学习 docker 架构 mosn细节 与微服务框架整合 Java动态代理 编程范式 并发通信模型 《网络是怎样连接的》笔记 go channel codereview gc分析 jvm 线程实现 go打包机制 go interface及反射 如何学习Kubernetes 《编译原理之美》笔记——后端部分 《编译原理之美》笔记——前端部分 Pilot MCP协议分析 go gc 内存管理玩法汇总 软件机制 istio流量管理 Pilot源码分析 golang io 学习Spring mosn源码浅析 MOSN简介 《datacenter as a computer》笔记 学习JVM Tomcat源码分析 Linux可观测性 学习存储 学计算 Gotty源码分析 kubernetes operator kaggle泰坦尼克问题实践 kubernetes扩缩容 神经网络模型优化 直觉上理解深度学习 如何学习机器学习 TIDB源码分析 什么是云原生 Alibaba Java诊断工具Arthas TIDB存储——TIKV 《Apache Kafka源码分析》——简介 netty中的线程池 guava cache 源码分析 Springboot 启动过程分析 Spring 创建Bean的年代变迁 Linux内存管理 自定义CNI IPAM 共识算法 spring redis 源码分析 kafka实践 spring kafka 源码分析 Linux进程调度 让kafka支持优先级队列 Codis源码分析 Redis源码分析 C语言学习 《趣谈Linux操作系统》笔记 docker和k8s安全访问机制 jvm crash分析 Prometheus 学习 Kubernetes监控 容器日志采集 Kubernetes 控制器模型 容器狂占资源怎么办? Kubernetes资源调度——scheduler 时序性数据库介绍及对比 influxdb入门 maven的基本概念 《Apache Kafka源码分析》——server Kubernetes类型系统 源码分析体会 《数据结构与算法之美》——算法新解 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 ansible学习 Kubernetes源码分析——从kubectl开始 jib源码分析之Step实现 jib源码分析之细节 线程排队 跨主机容器通信 jib源码分析及应用 为容器选择一个合适的entrypoint kubernetes yaml配置 《持续交付36讲》笔记 mybatis学习 程序猿应该知道的 无锁数据结构和算法 CNI——容器网络是如何打通的 为什么很多业务程序猿觉得数据结构和算法没用? 串一串一致性协议 当我在说PaaS时,我在说什么 《数据结构与算法之美》——数据结构笔记 PouchContainer技术分享体会 harbor学习 用groovy 来动态化你的代码 精简代码的利器——lombok 学习 《深入剖析kubernetes》笔记 编程语言那些事儿 rxjava3——背压 rxjava2——线程切换 spring cloud 初识 《深入拆解java 虚拟机》笔记 《how tomcat works》笔记 hystrix 学习 rxjava1——概念 Redis 学习 TIDB 学习 如何分发计算 Storm 学习 AQS1——论文学习 Unsafe Spark Stream 学习 linux vfs轮廓 《自己动手写docker》笔记 java8 实践 中本聪比特币白皮书 细读 区块链泛谈 比特币 大杂烩 总纲——如何学习分布式系统 hbase 泛谈 forkjoin 泛谈 看不见摸不着的cdn是啥 《jdk8 in action》笔记 程序猿视角看网络 bgp初识 calico学习 AQS——粗略的代码分析 我们能用反射做什么 web 跨域问题 《clean code》笔记 《Elasticsearch权威指南》笔记 mockito简介及源码分析 2017软件开发小结—— 从做功能到做系统 《Apache Kafka源码分析》——clients dns隐藏的一个坑 《mysql技术内幕》笔记 log4j学习 为什么netty比较难懂? 递归、回溯、动态规划 apollo client源码分析及看待面向对象设计 学习并发 docker运行java项目的常见问题 OpenTSDB 入门 spring事务小结 分布式事务 javascript应用在哪里 《netty in action》读书笔记 netty对http2协议的解析 ssl证书是什么东西 http那些事 苹果APNs推送框架pushy apple 推送那些事儿 编写java框架的几大利器 java内存模型和jvm内存布局 java exception Linux IO学习 netty内存管理 测试环境docker化实践 netty在框架中的使用套路 Nginx简单使用 《Linux内核设计的艺术》小结 Go并发机制及语言层工具 Linux网络源代码学习——数据包的发送与接收 《docker源码分析》小结 docker namespace和cgroup zookeeper三重奏 数据库的一些知识 Spark 泛谈 链式处理的那些套路 netty回顾 Thrift基本原理与实践(二) Thrift基本原理与实践(一) 回调 异步执行抽象——Executor与Future Docker0.1.0源码分析 java gc Jedis源码分析 深度学习泛谈 Linux网络命令操作 JTA与TCC 换个角度看待设计模式 Scala初识 向Hadoop学习NIO的使用 以新的角度看数据结构 并发控制相关的硬件与内核支持 systemd 简介 quartz 源码分析 基于docker搭建测试环境(二) spring aop 实现原理简述 自己动手写spring(八) 支持AOP 自己动手写spring(七) 类结构设计调整 分析log日志 自己动手写spring(六) 支持FactoryBean 自己动手写spring(九) 总结 自己动手写spring(五) bean的生命周期管理 自己动手写spring(四) 整合xml与注解方式 自己动手写spring(三) 支持注解方式 自己动手写spring(二) 创建一个bean工厂 自己动手写spring(一) 使用digester varnish 简单使用 关于docker image的那点事儿 基于docker搭建测试环境 分布式配置系统 JVM执行 git maven/ant/gradle/make使用 再看tcp kv系统 java nio的多线程扩展 《Concurrency Models》笔记 回头看Spring IOC IntelliJ IDEA使用 Java泛型 vagrant 使用 Go常用的一些库 Python初学 Goroutine 调度模型 虚拟网络 《程序员的自我修养》小结 Kubernetes存储 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件 Go基础 JVM类加载 硬币和扑克牌问题 LRU实现 virtualbox 使用 ThreadLocal小结 docker快速入门

架构

大模型推理服务框架 模型服务化(未完成) 大模型RHLF 大模型训练 大模型推理 从Attention到Transformer k8s设备管理 LLM工具栈 ddd从理念到代码 如何应用LLM 小鼠如何驾驭大象(LLM)? 多类型负载协调员Koordinator controller-runtime细节分析 finops学习 kubevela多集群 kubevela中cue的应用 基于k8s的工作流 容器和CPU那些事儿 kubevela源码分析 数据集管理fluid 应用管理平台kubevela karmada支持crd 多集群管理 AutoML和AutoDL 特征平台 实时训练 分布式链路追踪 helm tensorflow原理——python层分析 如何学习tensorflow 数据并行——allreduce 数据并行——ps 机器学习中的python调用c 机器学习训练框架概述 embedding的原理及实践 tensornet源码分析 大模型训练和推理 X的生成——特征工程 tvm tensorflow原理——core层分析 模型演变 《深度学习推荐系统实战》笔记 keras 和 Estimator tensorflow分布式训练 分布式训练的一些问题 基于Volcano的弹性训练 图神经网络 pytorch弹性分布式训练 从混部到统一调度 从RNN到Attention pytorch分布式训练 CNN 《动手学深度学习》笔记 pytorch与线性回归 多活 volcano特性源码分析 推理服务 kubebuilder 学习 mpi 学习pytorch client-go学习 tensorflow学习 提高gpu 利用率 GPU与容器的结合 GPU入门 AI云平台梳理 tf-operator源码分析 k8s批处理调度/Job调度 喜马拉雅容器化实践 Kubernetes 实践 学习rpc BFF openkruise学习 可观察性和监控系统 基于Kubernetes选主及应用 《许式伟的架构课》笔记 Admission Controller 与 Admission Webhook 发布平台系统设计 k8s水平扩缩容 Scheduler如何给Node打分 Scheduler扩展 深入controller openkruise cloneset学习 controller-runtime源码分析 pv与pvc实现 csi学习 client-go informer源码分析 kubelet 组件分析 调度实践 Pod是如何被创建出来的? 《软件设计之美》笔记 mecha 架构学习 Kubernetes events学习及应用 CRI 资源调度泛谈 业务系统设计原则 grpc学习 元编程 以应用为中心 istio学习 下一代微服务Service Mesh 《实现领域驱动设计》笔记 概率论 serverless 泛谈 《架构整洁之道》笔记 处理复杂性 那些年追过的并发 服务器端编程 网络通信协议 架构大杂烩 如何学习架构 《反应式设计模式》笔记 项目的演化特点 反应式架构摸索 函数式编程的设计模式 服务化 ddd反模式——CRUD的败笔 研发效能平台 重新看面向对象设计 业务系统设计的一些体会 函数式编程 《左耳听风》笔记 业务程序猿眼中的微服务管理 DDD实践——CQRS 项目隔离——案例研究 《编程的本质》笔记 系统故障排查汇总及教训 平台支持类系统的几个点 代码腾挪的艺术 abtest 系统设计汇总 《从0开始学架构》笔记 初级权限系统设计 领域驱动理念 现有上传协议分析 移动网络下的文件上传要注意的几个问题 推送系统的几个基本问题 做配置中心要想好的几个基本问题 不同层面的异步 分层那些事儿 性能问题分析 用户认证问题 资源的分配与回收——池 消息/任务队列

标签

k8s设备管理 多类型负载协调员Koordinator controller-runtime细节分析 finops学习 kubevela多集群 kubevela中cue的应用 基于k8s的工作流 容器和CPU那些事儿 kubevela源码分析 数据集管理fluid 应用管理平台kubevela karmada支持crd 多集群管理 helm 从混部到统一调度 volcano特性源码分析 kubebuilder 学习 client-go学习 tf-operator源码分析 k8s批处理调度/Job调度 喜马拉雅容器化实践 Kubernetes 实践 openkruise学习 基于Kubernetes选主及应用 Admission Controller 与 Admission Webhook k8s水平扩缩容 Scheduler如何给Node打分 Scheduler扩展 深入controller openkruise cloneset学习 controller-runtime源码分析 pv与pvc实现 csi学习 client-go informer源码分析 kubelet 组件分析 调度实践 Pod是如何被创建出来的? Kubernetes events学习及应用 CRI 资源调度泛谈 如何学习Kubernetes 以应用为中心 kubernetes operator kubernetes扩缩容 serverless 泛谈 什么是云原生 自定义CNI IPAM docker和k8s安全访问机制 Kubernetes监控 Kubernetes 控制器模型 Kubernetes资源调度——scheduler Kubernetes类型系统 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 Kubernetes源码分析——从kubectl开始 kubernetes yaml配置 CNI——容器网络是如何打通的 当我在说PaaS时,我在说什么 《深入剖析kubernetes》笔记 Kubernetes存储 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件

《数学之美》笔记

2019年06月15日

简介

通过数学之美,初步的建立起来 数学及其应用之间的关系,但对数学模型的物理意义仍然不够通透,要继续学习。

自然语言处理

文字、语言、数字、信息 ==> 信息科学规律的引导

大约是公元前32世纪, 埃及象形文字的数量大约只有500个,但到了公元前5-7世纪,象形文字增加到了5000个左右,与中国常用的汉字数量相当。然而随着文明的进步, 信息量的增加,埃及的象形文字数量便不再随着文明的发展而增加了,因为没有人能够学会和记住这么多文字。于是,概念的第一次概括和归类就开始了。比如汉字“日”表示太阳,同时又是太阳从升起到落山再到升起的一天。这种概念的聚类,在原理上与今天自然语言处理或者机器学习的聚类有很大的相似性,只是在远古,这个过程可能需要上千年。

文字出现在远古“信息爆炸”导致人们的头脑装不下这些信息的时候, 那么数字则是出现在人们的财产多到需要数一数才搞清楚有多少的时候。毫无疑问,如果我们有十二个指头,今天我们用的一定是十二进制。当然,算上脚指头有二十进制的,这就是玛雅文明。

阿拉伯数字的革命性不仅在于它的简洁有效, 而且标志着数字和文字的分离。作为对比,中国的个十百千万亿就没有分离。

从象形文字进化到拼音文字是一个飞跃,因为人类在描述物体的方式上,从物体的外表进化到了抽象的概念。同时不自觉地的采用了对信息的编码。在罗马体系的文字中, 总体来讲,常用字短,生僻字长。而在意型文字(比如中文)中,也是类似,大都常用字笔画少,而生僻字笔画多。这完全符合信息论中的最短编码原理。 这种文字(其实就是编码的方法)带来的好处是书写起来省时间、省材料(纸张要么没有要么不便宜)。

如果说从字母到词的构词法是词的编码规则,那么语法则是语言的编码和解码规则。不过相比较而言,词可以被认为是有限而封闭的集合,而语言则是无限和开放的集合。从数学上讲,对于前者可以有完备的编解码规则,而后者则不具备这个特性。 因此任何语言都有语法规则覆盖不到的地方,这些例外或者说不精确性,让我们的语言丰富多彩(也可以说是病句)。这就涉及到一个语言学研究方法的问题:到底是语言对,还是语法对。前者坚持从真实的语句文本(成为语料)出发,而后者坚持从规则出发,最终自然语言处理的成就宣布了前者的获胜。

语言的出现是为了人类之间的通信。字母(或中文的笔画)、文字和数字实际上是信息编码的不同单位。任何一种语言都是一种编码的方式,而语言的语法规则则是编解码的算法。我们把一个要表达的意思,通过某种语言的一句话表达出来,就是用这种语言的编码方式对头脑中的信息做了一次编码,编码的结果就是一串文字。而如果对方懂得这门语言,他或者她就可以用这门语言的解码方法获得说话人要表达的信息。这就是语言的数学本质

从规则到统计

自然语言从它产生开始,逐渐演变成一种上下文相关的信息表达和传递的方式。基于规则的方法在“上下文相关”的处理上捉襟见肘。PS:就好比听一个相声,包袱的最后一句话本身并不搞笑,而是全文的铺垫才起到了搞笑的效果。

从规则到统计,使得,可以且只需用数学的方法给出现今所有自然语言处理相关问题的全部答案。

  1. 牛顿:自然哲学的数学原理
  2. 香农:通信的数学原理

基于统计的自然语言处理方法, 在数学模型上和通信是相通的,甚至就是相同的。因此,在数学意义上自然语言处理又和语言的初衷——通信联系在一起了。但是,科学家用了几十年才认识到这个联系。

统计语言模型

直接命中 vs 先出几个备选,再根据统计决定哪个备选的可能性最大

任何方法都有它的局限性,因为统计语言模型很大程度上是依照“大众的想法”或者“多数句子的用法”,而在特定的情况下可能是错的。

图灵测试:如果人无法判断自己交流的对象是人还是机器,就说明这个机器有智能了。

语音识别

逻辑链条:

  1. 统计语言模型产生的初衷是为了解决语音识别问题。在语音识别中,计算机需要知道一个文字序列是否能构成一个大家理解而且有意义的句子, 然后显示或者打印给使用者。
  2. 一个句子是否合理,就看它的可能性大小如何,至于可能性就用概率来衡量。PS:在人类说过的所有话中出现的可能性。
  3. 假设S表示某一个有意义的句子, 由一连串特定顺序排序的词w1,w2,...wn组成,这里的n是句子的长度。S=w1,w2,...wn,S在文本中出现的可能性也就是数学上的概率P(S),即把人类有史以来讲过的话统计一下, 就知道这句话可能出现的概率了,但傻子都知道行不通。将P(S)展开表示P(S)=P(w1,w2,...wn)
  4. 利用条件概率的公式,P(w1,w2,...wn)=P(w1).P(w2|w1).P(w3|w1,w2)...P(wn|w1,w2,...wn-1)
  5. 可以看到P(w1) 比较好算,P(w3|w1,w2)已经非常难算了,P(wn|w1,w2,...wn-1)的可能性太多,无法估算。为此,俄国数学家马尔科夫提出了一种偷懒但颇为有效地方法:即假设任意一个词wi出现的概率只同它前面的词wi-1 有关,于是公式就可以转换为 P(w1,w2,...wn)=P(w1).P(w2|w1).P(w3|w2)...P(wn|wn-1),对应的统计语言模型叫二元(文法)模型。当然,也可以假设一个词由前面的N-1个词决定,称为N元模型。
  6. 现在的问题就变成了 如何计算条件概率 P(wi|wi-1),根据它的定义 P(wi|wi-1) = P(wi-1,wi)/P(wi-1),而估计联合概率P(wi-1,wi)P(wi-1),因为有了大量的机读文本(也就是语料库)而变得很简单。只要数一数wi-1,wi 这对词在统计文本中前后相邻出现了多少次#(wi-1,wi),以及wi-1本身在同样的文本中出现了多少次#(w-1),然后用两个数分别除以语料库的大小#,即可得到词或二元组的相对频度。

     f(wi-1,wi)= #(wi-1,wi) / #
     f(wi-1) = #(wi-1) / #
     // 根据大数定理, 只要统计量足够, 相对频度就等于概率
     P(wi-1,wi) 约等于 #(wi-1,wi) / #
     P(wi-1) 约等于 #(wi-1) / #
     // 因此
     P(wi|wi-1) = P(wi-1,wi)/P(wi-1) = #(wi-1,wi) / #(wi-1) 
    
  7. 经过一系列转换,P(S) 计算的基本单元变成了统计词和二元组 在语料库中出现的次数,这是计算机的拿手活。PS:Hadoop的demo 是WordCount 估计就是因为这个

PS: 自然语言是一种上下文相关的信息表达和传递的方式,那自然语言处理模型里一定要体现“上下文相关”的处理思路

中文分词

  1. 北航的梁南元教授最早提出“查字典”的方法,将句子从左到右扫描一遍,遇到“字典”里有的词就标识出来,遇到复合词就找最长的匹配,遇到不认识的字串就分割成单字词。
  2. 哈工大的王晓龙博士将查字典的方法理论化,发展成最少词数的分词理论,即一句话应该分成数量最少的词串
  3. 清华大学的郭进博士用统计语言模型成功解决了分词二义性问题,将汉语分词的错误率降低了一个数量级

假定一个句子S可以有几种分词方法,为了简单起见, 假定有以下三种

A1,A2,A3,...,Ak
B1,B2,B3,...,Bm
C1,C2,C3,...,Cn

其中A1,A2,B1,B2,C1,C2 都是汉语的词,以上各种分词结果可能产生不同数量的词串(也就是,有的分词方式分出来的词多,有的分出来的词少),k,m,n 表示不同的数目。那么最好的一种分词方法应该保证分完词后这个句子出现的概率最大。也就是说,如果A1,A2,A3,…,Ak 是最好的分词方法,那么其概率应该满足P(A1,A2,A3,...,Ak) > P(B1,B2,...,Bm) 并且 P(A1,A2,A3,...,Ak) > P(C1,C2,...,Cn)

隐含马尔科夫模型

通信的本质是一个编解码和传输的过程,但自然语言处理早期的努力都集中在语法、语义和知识表述上,离通信的原理越走越远,而这样离答案也就越走越远。当自然语言处理的问题回归到通信中的解码问题时,很多难题都迎刃而解了。

在通信中,如何根据接收端的观测信号o1,o2,o3,... 来推测信号源发送的信息s1,s2,s3,... 呢?只需要从所有的源信息中找到最可能产生观测信号的那一个信息。用概率论的语言来描述, 就是在已知o1,o2,o3,...的情况下,求得令条件概率P(s1,s2,s3,...|o1,o2,o3,...)达到最大值的那个信息串s1,s2,s3,...

感觉需要买本随机过程的书 补一下基础

【机器学习研究】隐马尔可夫模型 (HMM) 最认真研究 如何根据海藻的变化推测天气?

信息的度量和作用

一本50w字的《史记》有多少信息量, 或者一套莎士比亚全集有多少信息量。我们常说信息有用,那它的作用如何客观、定量的体现出来呢?直到1948年,香农在他著名的论文“通信的数学原理”中提出了信息熵的概念,才解决了信息的度量问题,并且量化出信息的作用。

一条信息的信息量与其不确定性有着直接的关系。比如搞懂一无所知的事情,要了解大量的信息,而如果对某事了解较多,则不需要太多的信息就能把他搞清楚。从这个角度看,信息量就等于不确定性的多少。

搜索

建立一个搜索引擎大致需要做这样几件事:自动下载尽可能多的网页;建立快速有效地索引;根据相关性对网页进行公平准确的排序。所以吴军到了腾讯之后,就把搜搜所有的搜索产品都提炼成下载、索引和排序这三种基本服务,这就是搜索的“道”。所有的搜索服务都可以在这三个基本服务的基础上很快实现,这就是搜索的“术”。

布尔代数提出后80多年里, 它确实没什么像样的运用,直到1938年香农在他的硕士论文中指出用布尔代数来实现开关电路,才使得布尔代数成为数字电路的基础。所有数据和逻辑运算,加、减、乘、除、乘方、开方等等,全都能转换成二值的布尔运算。正是依靠这一点,人类用一个开关电路最终“搭出”电子计算机。 数学的发展实际上是不断地抽象和概括的过程,这些抽象了的方法看似离生活越来越远,但是它们最终能找到适用的地方,布尔代数便是如此。

布尔代数对于数学的意义等同于量子力学对于物理学的意义,它们将我们对世界的认识从连续状态扩展到离散状态。在布尔代数的世界里, 万物都是可以量子化的,从连续的变成一个个分离的,它们的运算“与、或、非”也就和传统的代数运算完全不同了。现代物理的研究成果表明,我们的世界实实在在是量子化的而不是连续的。

对于一个特定的查询,搜索结果的排名取决于两组信息:关于网页的质量信息(Quality),以及这个查询与每个网页的相关性信息(Relevance)。

PageRank

Google的PageRank是计算网页自身质量的完美的数学模型,其简单地说就是民主表决。 一个网页的质量是由所有包含它链接的网页共同决定的。 在互联网上,如果一个网页被很多其他网页所链接,说明它受到普遍的承认和信赖,那么它的排名就高。 这就是PageRank的核心思想。 但是,所有网页的表决权是不一样的,即网页排名高的网站的贡献的链接权重理应要大。网页Y的排名来自于所有指向这个网页的其他网页X1,X2,…,Xk的权重之和。但是,网页X1,X2,…,Xk的权重又应该是其自身的网页排名(PageRank)。因此,计算这些网页的排名又会用到更多指向它们的网页的排名, 这就变成了一个怪圈。PageRank算法把这个问题变成了一个二维矩阵相乘的问题,并用迭代的方法解决了这个问题。

这个动作用数学提炼一下就是:一个向量 B=(b1,b2,...,bn) 和一个矩阵A ,假定B0=(1/N,1/N,1/N)(随便定的),Bi = A*Bi-1,经过n次迭代, Bi无限趋近与B,此时 B = B * A,说白了就是已知矩阵A,对于任何设定的初始向量B0,不断迭代,都可以找到一个向量B,使得B = B * A

孟岩理解矩阵 理解矩阵的经典文章,主要结论:

  1. 首先有空间,空间可以容纳对象运动的。一种空间对应一类对象。
  2. 有一种空间叫线性空间,线性空间是容纳向量对象运动的。
  3. 运动是瞬时的,因此也被称为变换。
  4. 矩阵是线性空间中运动(变换)的描述。
  5. 矩阵与向量相乘,就是实施运动(变换)的过程。
  6. 同一个变换,在不同的坐标系下表现为不同的矩阵,但是它们的本质是一样的,所以本征值相同。
  7. 矩阵(与矩阵的)的乘法变成了运动的施加。只不过,被施加运动的不再是向量,而是另一个坐标系。
  8. 然而数学公理化的一个备受争议的副作用,就是一般数学教育中直觉性的丧失。数学家们似乎认为直觉性与抽象性是矛盾的,因此毫不犹豫地牺牲掉前者。然而包括我本人在内的很多人都对此表示怀疑,我们不认为直觉性与抽象性一定相互矛盾,特别是在数学教育中和数学教材中,帮助学生建立直觉,有助于它们理解那些抽象的概念,进而理解数学的本质。反之,如果一味注重形式上的严格性,学生就好像被迫进行钻火圈表演的小白鼠一样,变成枯燥的规则的奴隶。

如果将矩阵看做运动,对于运动而言,最重要的当然就是运动的速度和方向,那么

  1. 特征值就是运动的速度
  2. 特征向量就是运动的方向

既然运动最重要的两个方面都被描述了,特征值、特征向量自然可以看做运动(矩阵)的特征。注意,由于矩阵是数学概念,非常抽象,所以上面所谓的运动、速度、方向都是广义的,在不同的应用中有不同的指代。

学习PageRank算法,必先了解特征值与特征向量

在实际应用中,向量和矩阵是干不了多少事的。机械振动和电振动有频谱,振动的某个频率具有某个幅度;那么矩阵也有矩阵的谱,矩阵的谱就是矩阵特征值的概念,是矩阵所固有的特性,所有的特征值形成了矩阵的一个频谱,每个特征值是矩阵的一个“谐振频点”。

美国数学家斯特让(G..Strang)在其经典教材《线性代数及其应用》中这样介绍了特征值作为频率的物理意义,他说:大概最简单的例子(我从不相信其真实性,虽然据说1831年有一桥梁毁于此因)是一对士兵通过桥梁的例子。传统上,他们要停止齐步前进而要散步通过。这个理由是因为他们可能以等于桥的特征值之一的频率齐步行进,从而将发生共振。就像孩子的秋千那样,你一旦注意到一个秋千的频率,和此频率相配,你就使频率荡得更高。一个工程师总是试图使他的桥梁或他的火箭的自然频率远离风的频率或液体燃料的频率;而在另一种极端情况,一个证券经纪人则尽毕生精力于努力到达市场的自然频率线。特征值是几乎任何一个动力系统的最重要的特征

如果一个物理系统其特性可以被一个矩阵所描述,那么这个系统的物理特性就可以被这个矩阵的特征值所决定,各种不同的信号(向量)进入这个系统中后,系统输出的信号(向量)就会发生相位滞后、放大、缩小等各种纷乱的变化。但只有特征信号(特征向量)被稳定的发生放大(或缩小)的变化。如果把系统的输出端口接入输入端口,那么只有特征信号(特征向量)第二次被放大(或缩小)了,其他的信号如滞后的可能滞后也可能超前同时缩小,放大的可能被继续放大也可能被缩小同时滞后,缩小的可能被继续缩小也可能被放大同时滞后等。经过N次的循环后,显然,乱七八糟的大量的向量群众们终不能成气候,只有特征向量们,心往一处想,劲往一处使,要么成功出人头地,要么失败杀身成仁。因此我们就可以因此在时间域上观察输出,就会得到一个或几个超级明显的特征信号出来(特征向量)。

笔者的两个体会:

  1. 如何表达一个人的一生?你可以将一个人的一生全部录下来,也可以将它浓缩为一个两小时的电影,也可以浓缩为一个墓志铭。万事万物在它纷繁的表象之下,都有其本质。如果一个事物可以用矩阵来表示,那么特征向量就是这个矩阵(事物)浓缩后的本质之一。
  2. 看一个墓志铭总比看一个人的一生要容易,很自然,根据表象提炼本质是人类的普遍追求,如果可以用数学表达,用计算机计算出来就更爽了
  3. 矩阵是线性空间中运动(变换)的描述,社会也是不断变迁的,如果你按“特征向量”行事,就可以用最少的力达成最大的位移,就像荡秋千,要顺着秋千的“劲道”。但无论如何,不管你顺不顺应,人都逃不过历史的进程,就像pagerank 先随便假定一个向量,和矩阵迭代做乘法,终归会逼近 矩阵的特征向量。无论你在秋千上如何挣扎,秋千的摆球运动轨迹你改不了。无论个体差异多么的大,都会成为时代的一部分。

文本分类

假设词汇表中有64000个词,每一个词的重要性不同(这个可以由单文本词汇频率/逆文本频率值TF-IDF 来表示)。如果单词表中某个词在新闻中没有出现,对应的值为0,那么这64000个数,组成一个64000维的向量。我们用这个向量来代表这篇新闻,并称之为新闻的特征向量。每一个新闻都可以对应这样一个特征向量, 向量中每一个维度的大小代表每个词对这篇新闻主题的贡献。

几千年来,人类已经形成这样的写作习惯,同一类新闻一定是某些主题词用的比较多, 另一些词则用的比较少。反映在每一篇新闻的特征上,如果两篇新闻属于同一类, 它们的特征向量在某几个维度的值都比较大, 而在其他维度的值都比较小。 反过来看,不属于同一类的新闻由于用词的不同,在它们的特征向量中,值较大的维度应该没什么交集。这样我们就定性的认识到,两篇新闻的主题是否接近,取决于它们的特征向量“长得像不像”。那么,如何定量的衡量两个特征向量之间的相似性?

向量实际上是多维空间中从原点出发的有向线段。向量包括长度和方向,考察向量的相似性自然也离不开这两个属性。不同的新闻,因为文本长度的不同,它们的特征向量在各个维度的数值也不同。一篇10000字的文本,各个维度的值都比一篇500字的文本来的大。因此单纯比较各个维度的大小并没有太大意义,但是向量的方向很有意义, 如果两个向量的方向一致,说明相应的新闻用词的比例基本一致。 因此,可以通过计算两个向量的夹角来判断对应的新闻主题的接近程度。而要计算两个向量的夹角,就要用到余弦定理了。余弦定理描述了三角形中任何一个夹角和三个边的关系。

总结一下就是:将新闻变成代表它们内容的实词,然后再变成一组数,具体说是向量,最后求这两个向量的夹角。

信息指纹

视频的匹配有两个核心技术,关键帧的提取和特征的提取。MPEG视频虽然每秒钟有30帧图像, 但是每一帧之间的差异不大。一般来说, 每一秒或若干秒才有一帧是完整的图像, 这些帧称为关键帧,其余帧存储的只是和关键帧相比的差异值。关键帧对于视频的重要性,就如同主题词对于新闻的重要性一样。

逻辑回归

一件事由很多因素决定,每个因素都有一个权重/概率。这么多因素用一个统一的数学模型来描述并不容易, 更何况我们还希望这个模型能够随着数据量的增加越做越准确。

  1. 逻辑回归模型:z=p1x1+p2x2+p3x3x是影响z的因素,p是该因素的权重,剩下的问题就是如何根据数据 拿到 尽量准确的p值
  2. 期望最大模型
  3. 最大熵模型

机器学习

人工神经网络这个词儿听起来像是用人工的方法模拟人脑, 加上它使用了一些与生物有关的名词如“神经元”等等,让人感觉很神秘。其实除了借用生物学上的一些名词,并且做了一些形象的比喻外,人工神经网络和人脑没有半点关系,它本质上是一种有向图,只不过是一种特殊的有向图。有向图包括节点和连接节点的有向弧,在神经网络里分别被称为神经元和连接神经元的神经。其特殊性体现在

  1. 图中的所有节点都是分层的,每一层节点可以通过有向弧指向上一层节点, 但是同一层节点之间没有弧互相连接,而且每一个节点不能越过一层连接到上上层的节点上。
  2. 每一条弧都有一个值(权重),根据这些值,可以用一个非常简单的公式算出它们所指节点的值,这个公式称为神经元函数。
  3. 神经元函数是如何选取的?显然,如果允许这些函数随便选取,设计出来的分类器可以非常灵活, 但是这样一来,相应的人工神经网络就缺少了通用性,而且这些函数的参数也很难训练。因此,在人工神经网络中,规定神经元函数只能对输入变量(指向它的节点的值)线性组合后的结果进行一次非线性变换。比如节点X1,X2,...,Xn指向Y,这些节点的值分别为x1,x2,...,xn,相应弧的权重分别为w1,w2,...,wn。计算节点Y的取值y分两步

    1. 第一步是计算来自这些x1,x2,...,xn的线性组合 G=w0 + x1*w1 + x2*w2 + ... + xn.wn
    2. 计算 y=f(G),虽然f 本身可以是非线性的,但由于它只接受G一个变量,因此不会很复杂。

读者可能会问,然后呢?没有然后了,人工神经网络就是这么简单!这么简单的东西有什么用呢?因为无论是在计算机科学、通信、生物统计和医学,还是在金融和经济学(包括股市预测)中,大多数与智能有点关系的问题, 都可以归结为一个在多维空间进行模式分类的问题,而人工神经网络所擅长的正是模式分类。模式分类的任务就是要在空间里划一刀,在二维空间里,这一刀可以是直线,也可以是曲线。在高维空间是曲面。从理论上讲, 人工神经网络可以在多维空间“画出”各种形状的模式分类边界(曲线/曲面)。PS:要么找到规律,找到曲线、曲面的函数表示,要么通过数据训练,无限逼近它们。

在模式分类里, 一个模式(图像、语音、文字等)的特征值(比如坐标),从输入层开始,按照上面的规则和公式一层层向后传递, 最后到输出层,哪个节点的数值最大,输入的模式就被分在了哪一类。这就是人工神经网络的基本原理。 值得指出的是,如果我们把不同输出节点上得到的值看成是一种概率分布(PS:说的是离散分布的一个值?),那么实际上人工神经网络就等价于一个概率模型了。

对于有监督训练,假设C是一个成本函数,它表示根据人工神经网络得到的输出值y(w)(分类结果)和实际训练中的输出值之间的差距,比如可以定义C=E(y(w)-y)^2(欧几里得距离),我们训练的目标是找到一个w,使得C最小。 进而,训练神经网络的问题就变成了一个最优化的问题。解决最优化问题的常用方法就是梯度下降法。 不过,实际应用中我们常常无法获得大量标注好的数据,只有输入数据(x),而没有对应的输出数据(y),成本函数C就无法使用了, 我们无从得知模型产生的输出值和正确的输出值之间的误差是多少。因此,我们需要定义一种新的(而且容易计算的)成本函数,它能够在不知道正确的输出值的情况下, 确定(或预估)训练出的模型的好坏。研究人员需要根据具体的应用来寻找合适的函数,不过总体来说,成本函数总要遵循一个原则:既然人工神经网络解决的是分类问题,那么我们希望分完类之后, 同一类样本(训练数据)应该相互比较靠近, 而不同类样本应该尽可能的远离。无监督训练定义了成本函数之后,就可以使用梯度下降法进行无监督的参数训练了。

人工神经网络的结构 来源  
网络分几层    
每层几个节点    
非线性函数f的设计   如果使用指数函数f(G)=e^G,则其模式分类能力等价于最大熵模型
参数w1,w2,...,wn的值 依靠数据训练  
有监督训练——成本函数   比如欧几里得距离
无监督训练——成本函数 随应用而不同 多维空间的模式分类问题,成本函数=聚类中心的欧几里得距离的均值
估计语言模型的条件概率, 成本函数=熵

PS:我们不能因为人工神经网络很热,就认为它是唯一方案,只是它的一些特点导致它与现阶段的技术能力比较适配,并了解它的一些局限。

  人工神经网络 贝叶斯网络 备注
有向图  
节点的值 只与上一级有关 只与前一级有关  
训练方法 有监督、无监督 训练结构
训练参数
两者交替进行,直到收敛或误差足够小
相似
神经元函数 线性变换G+f(G) 任意函数  
处理序列 比较难 相对容易 贝叶斯网络更容易考虑上下文的相关性
人工神经网络的输出相对孤立
特点 标准化 比较灵活 所以人工神经网络更容易工程实现,一次开发、长期使用
并行化 容易 很难 能够充分利用云计算的能力

算法与数据之争

《数学之美》:在2007年,技术和算法的重要性依然高于数据,因此确定网页和查询的相关性主要依靠算法。但是今天,由于已经有了大量的用户点击数据,因此对搜索相关性贡献最大的是根据用户对常见搜索点击网页的结果得到的概率模型。PS:大数据使得概率论有了更大的用武之地。

PageRank算法的数学原理值得深思的是,计算机的普及让人们越来越趋于使用优质的数学模型、大量的数据和高效率的计算解决问题。逼近近似值求数值解的方法大行其道,并不代表优雅的解析公式不重要,如果不深入理解模型中参数的本质,如何能善用深度学习模型,怎么能因为归纳法效果好就不思考演绎法?

如何通俗易懂地讲解牛顿迭代法?如牛顿方法及其衍生算法,通过对线性函数作切线,几何方法逼近函数与x的交点,反复迭代,便得到了数值解。PS:找到f(x)=0的x,你可以一直不停的做切线,也可以直接根据公式求得f(x)=0的解。

大数据使得概率论有了用武之地,概率论中一系列公式中的部分值是可以直接计算出来的,自然另一部分是可以间接推算出来的。从上文看,受益的不只是概率论。在过去20年里, 在机器学习和自然语言处理领域, 80%的成果来自于数据量的增加。

在数学之美可以看到,给一个语料库(比如中文语料库,几十万到几百万有代表性的中文句子,带上词性标注(即一个词是动词还是名词))可以计算好多东西

  1. 一个词的但文本词频/逆文本频率指数 TF-IDF
  2. 一句话中,一次词出现时,另一个词出现的概率
  3. 语料库由一篇篇文章组成,可以使用文本和关键词关联矩阵的奇异值分解,或余弦距离等方式对文章进行聚类,对于一篇文章可以把它归到一类或若干类中, 同一类文章共享很多关键词, 这样不同的文章通过关键词建立一种关联关系,表明是否属于同一类。
  4. 如果把文本和关键词的关联矩阵转90度进行奇异值分解,或者对每个词以文本为维度,建立一个向量,再进行向量的聚类,那么得到是一个对词的分类(我们称为概念)。PS:对词进行聚类

没弄懂的

  1. 马尔科夫链
  2. 矩阵运算和文本处理中的两个分类问题
  3. 最大熵模型
  4. 逻辑回归

其它

少年教育

  1. 小学生和中学生其实没有必要花那么多时间读书,而他们的社会经验、生活能力以及在那时树立起的指向将帮助他们的一生
  2. 中学阶段花很多时间比同伴多读的课程, 上大学以后用很短的时间就能读完,因为在大学阶段,人的理解力要强的多
  3. 学习是持续一辈子的过程,若不是出于兴趣,持续学习的动力不足
  4. 书本的内容可以早学也可以晚学,但是错过了成长阶段却是无法补回来的

贾里尼克告诉吴军最多的是:什么方法不好。这一点与股神巴菲特给和他吃饭的投资人的建议有异曲同工之处,巴菲特和那些投资人讲,你们都非常聪明,不需要我告诉你们做什么,我只需要告诉你们不要做什么(这样可以少犯很多错误)。这些不要做的事情,是巴菲特从一生的经验教训中得到的。

先帮助用户解决80%的问题,再慢慢解决剩下的20%的问题,是在工业界成功的秘诀之一。许多失败并不是因为人不优秀,而是做事情的方法不对,一开始追求大而全的解决方案,之后长时间不能完成,最后不了了之。选择简单方案的另一个原因是容易解释每一个步骤和方法背后的道理, 这样不仅便于出了问题时查错,而且容易找到今后改进的目标。

虽然所有的视频都可以插入广告, 但广告的收益全部提供给原创的视频,即使广告是插入在拷贝的视频中。这样一来,所有拷贝和上传别人的视频的网站就不可能获得收入。没有了经济利益,也就少了很多盗版和拷贝。

搜索广告之所以比传统的在线展示广告赚钱多很多, 除了搜索者的意图明确外,更重要的是靠预测用户可能会点击哪些广告, 来决定在搜索结果页中插入哪些广告

一个好方法在形式上应该是简单的