Escape The Brain

  • Home

  • Tags

  • Archives

随机优化算法简介

Posted on 2019-04-19

随机优化算法特别适合用来解决受多个变量影响,存在很多可能的解,且结果因这些变量的组合而产生很大变化的问题。其典型的应用场景是,问题的解空间非常大,以至于我们无法对所有可能的解逐一尝试的情况。对于这类问题最简单低效的求解方法是尝试随机猜测成千上万个解,并从中找出最佳的解。更有效率的方法则是从随机解出发,朝着可能有改进的方向修正来逼近最优解。本文将从最低效的随机搜索算法出发,随后介绍更优的爬山法、模拟退火、遗传算法等随机优化算法。

成本函数(Cost Function)

成本函数是使用优化算法解决问题的关键。任何优化算法的目标,都是要寻找一组能够使得成本函数的结果最小化的解。因此,当我们给定一个解时,成本函数需要评估这个解的好坏,并返回一个值表示评估的结果,通常返回的值越大代表成本越高,即对应的解越差。

随机搜索(Random Searching)

随机搜索是一种简单低效的优化算法,虽然效果不是非常好,但是有助于我们理解其他的优化算法,也是我们评估其他算法的基线。

随机搜索会尝试 n 次的随机猜测,每次尝试的过程如下:

  1. 首先生成一个随机解;
  2. 随后使用成本函数评估成本;
  3. 与目前为止的最优解比较成本,如果成本更低则更新最优解及最优成本。

虽然 n 次的猜测在全部的可能性中只占非常小的一部分,得到最优解的几率很小,但我们仍然有机会得到还算不错的解。

Read more »

Kafka 的架构与设计概览

Posted on 2019-03-15

Kafka 是一个开源的分布式流处理平台,由 Scala 和 Java 编写。该项目的目标是为处理实时数据提供一个统一、高吞吐、低延迟的平台。

Kafka 的持久化层本质上是一个“按照分布式事务日志系统设计的大规模发布/订阅消息队列”,这使它作为企业级基础设施来处理流式数据时非常有价值。此外,Kafka 可以通过 Kafka Connect 连接到外部系统(用于数据输入/输出),并提供了 Kafka Streams(一个 Java 流式处理库)。

设计目标

Kafka 主要的设计目标如下:

  • 高吞吐
  • 低延迟
  • 提供持久化能力,并支持常数时间复杂度的访问性能。
  • 同时支持离线数据处理和实时数据处理。
  • 支持分区,及分布式消费,同时保证每个 Partition 内的消息顺序传输。
  • 容错性

Kafka 架构

Kafka 架构中一般包含由多个 Broker 组成的 Kafka 集群,以及多个 Producer 和多个 Consumer。其中涉及的一些关键概念如下:

  • Broker: Kafka 集群包含一个或多个服务器,这些服务器被称为 Broker。
  • Topic: 每条发布到 Kafka 集群的消息都有一个类别,这个类别被称为 Topic。也可以将每一个 Topic 理解为不同的消息队列。不同的 Topic 物理上将分开存储。
  • Partition: Parition 是物理上的概念,每个 Topic 包含一个或多个 Partition。这些 Partition 可能分布在不同的 Broker 上。
  • Producer: 消息的生产者,使用 push 模式将消息发布到 Broker。
  • Consumer: 消息的消费者,使用 pull 模式从 Broker 订阅并消费消息。
  • Consumer Group: 每个 Consumer 属于一个特定的 Consumer Group。一条消息在一个 Consumer Group 内只能被消费一次,但不同的 Consumer Group 可同时消费这一消息。
Read more »

Linux 常用文本处理命令

Posted on 2019-02-15 | Edited on 2019-03-14

Linux 系统有许多的工具用来对文本进行过滤和处理,下面对一些常用的工具进行简单总结。

grep

grep 工具对文件的每一行搜索指定的模式字符串。如果找到了匹配这个字符串的行,就打印该行的内容。

基本语法

1
2
3
grep [OPTIONS] PATTERN [FILE...] 

grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

常用选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 指定pattern,可用于需要匹配多个模式的情况
-e PATTERN

# 指定文件中,每行存储一个模式
-f FILE

# 忽略大小写
-i, --ignore-case

# 反检索,只显示不匹配的行。
-v, --invert-match

# 匹配整个单词
-w, --word-regexp

# 匹配整行
-x, --line-regexp


# 只输出匹配的行数,不显示匹配的内容。
-c, --count

# 高亮匹配的字符串
# WHEN is never, always, auto
--color[=WHEN]

# 搜索多个文件时,不显示匹配文件名
-h,--no-filename

# 显示行号
-n,--line-number

# 只显示匹配的部分
-o, --only-matching

# 不显示错误信息。
-s,--no-messages

# 不显示信息,只返回退出状态。0表示匹配成功
-q,--quiet

# 列出匹配成功的文件
-l,--files-with-matches

# 列出不匹配模式的文件
-L,--files-without-match
Read more »

Matplotlib 简明教程

Posted on 2019-01-15 | Edited on 2019-03-14

Matplotlib 可以说是最常用的 Python 绘图模块,其实现了许多类似 Matlab 中的函数,可以帮助用户轻松获得高质量的图形。

Pyplot

matplotlib.pyplot 提供了一系列与 Matlab 绘图命令对应的函数,如果你熟悉 Matlab 绘图将很容易上手。

1
2
# 使用 Jupyter notebook 时在开头添加如下命令使图形嵌入当前页面
%matplotlib inline

绘制简单折线:

1
2
3
4
5
6
7
8
9
10
import matplotlib.pyplot as plt

plt.figure() # 创建一个新的图

plt.plot([1, 2, 3, 4], [1, 4, 9, 16]) # 传入一些 x 和 y 的值来绘制折线
plt.title('Line Chart: Polyline') # 设置标题
plt.xlabel('x') # 设置 x 轴标签文字
plt.ylabel('y') # 设置 y 轴标签文字

plt.show() # 显示图形

image

Read more »

Numpy 简明教程 - 数组的运算与操作

Posted on 2018-12-22 | Edited on 2019-03-14

基本运算

Numpy的数组支持算术运算、逻辑运算、常见数学函数等许多的运算功能。

算术运算

与标量的运算:

1
2
3
4
5
>>> a = np.array([1, 2, 3, 4])
>>> a + 1
array([2, 3, 4, 5])
>>> 2**a
array([ 2, 4, 8, 16])

数组元素的算术运算:

1
2
3
4
5
6
7
8
9
10
>>> a = np.array([1, 2, 3, 4])
>>> b = np.ones(4) + 1
>>> a - b
array([-1., 0., 1., 2.])
>>> a * b
array([ 2., 4., 6., 8.])

>>> j = np.arange(5)
>>> 2**(j + 1) - j
array([ 2, 3, 6, 13, 28])

这些操作远比在Python中直接实现效率要高的多:

1
2
3
4
5
6
>>> a = np.arange(10000)
>>> %timeit a + 1
10000 loops, best of 3: 24.3 us per loop
>>> l = range(10000)
>>> %timeit [i+1 for i in l]
1000 loops, best of 3: 861 us per loop

Read more »

Numpy 简明教程 - 多维数组

Posted on 2018-12-19 | Edited on 2019-03-14

数组对象

Numpy 核心的对象是 ndarray,表示多维数组,可以看作由类型相同(通常是数字)的元素组成的表。

可以通过官方教程的例子了解其基本属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> import numpy as np
>>> a = np.arange(15).reshape(3, 5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a.shape # 数组的形状(各维度大小)
(3, 5)
>>> a.ndim # 数组的维数
2
>>> a.dtype.name # 数组中元素的类型
'int64'
>>> a.itemsize # 数组中每个元素的字节大小
8
>>> a.size # 数组元素的总数
15
>>> type(a)
<type 'numpy.ndarray'>
>>> b = np.array([6, 7, 8])
>>> b
array([6, 7, 8])
>>> type(b)
<type 'numpy.ndarray'>

创建数组

Numpy中创建数组的方式很多,下面列举常见的创建数组的方式。

np.array()

我们可以使用array函数从 Python 的列表或元组创建数组。

Read more »

Redis GEO 相关命令简介

Posted on 2018-11-17

Redis GEO 特性(Redis版本>=3.2.0)支持对地理位置进行存储、空间索引、空间查询等相关操作。下面简要介绍其基本命令。

使用 GEOADD 添加位置

GEOADD 用于将给定的地理空间元素(纬度、经度、名称)添加到指定的集合(由key指定)中。Redis 内部会把对应的数据存储到一个 zset 有序集合中。存储时经纬度坐标会转换为 Geohash 值以实现空间索引,从而支持空间查询操作。

命令形式

1
GEOADD key longitude latitude member [longitude latitude member ...]

GEOADD 命令以 x,y 的格式接受经纬度参数,即经度在前,纬度在后。可以一次添加多个地理位置信息,即纬度、经度、名称可以重复多次。

GEOADD 支持的坐标范围是有限的,接近两极的坐标无法支持:

  • 有效的经度介于 -180 度至 180 度之间。
  • 有效的纬度介于 -85.05112878 度至 85.05112878 度之间。

GEOADD 每添加一个元素的时间复杂度为 O(log(N)) ,其中 N 为 key 对应的集合中的元素数量。

GEOADD 命令的返回值为新加入到集合中的地理空间元素的数量,集合中已存在的的元素(仅更新)不计入内。

Read more »

常用的概率定理

Posted on 2018-11-06 | Edited on 2019-03-14

本文总结了一些在计算概率时经常用到的定理,如乘法法则、贝叶斯定理等等。我们会首先回顾概率公理,然后介绍由概率公理引出的概率论中的常用定理。

概率公理

对于事件空间 S 中的每一个事件 A,可以通过一个函数 P 得到一个实数 P(A),并且该函数满足下面的 3 个公理,那么函数 P 叫做概率函数,相应的 P(A) 叫做事件 A 的概率。

公理 1

表示事件 A 的概率 P(A) 是一个0与1之间(包含0与1)的非负实数。

公理 2

表示事件空间总的概率值为 1 。

公理 3

表示互斥事件的加法法则。可以推广到可数个互斥事件的联集。

概率定理

我们可以从概率公理推导出以下的一些概率定理。

互补法则

与 A 互补事件的概率:

互补法则可以通过公理3和公理2证明。

Read more »

scikit-learn 笔记 - 模型选择与评估

Posted on 2018-11-02 | Edited on 2019-03-14

性能评估

为了防止模型过拟合训练数据,需要从数据集划分一部分数据到测试集,在独立的测试集上评估性能(泛化能力)。

scikit-learn 提供了多种评估方法,包括:

  • 学习器的 score 方法返回默认的评估指标。
  • 使用交叉验证的模型评估工具内部使用了相应的评分策略
  • metrics 模块实现了用于各种不同目的的性能评估指标。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import datasets
from sklearn import svm

# load the iris data set
iris = datasets.load_iris()
print iris.data.shape, iris.target.shape

# split into training and test sets
X_train, X_test, y_train, y_test = train_test_split(
iris.data, iris.target, test_size=0.4, random_state=0)
print X_train.shape, y_train.shape
print X_test.shape, y_test.shape

# evaluation classifier
clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)
print clf.score(X_test, y_test)
pred = clf.predict(X_test)
print(metrics.classification_report(y_test, pred))
print(metrics.confusion_matrix(y_test, pred))

交叉验证 (Cross Validation)

在评估不同的模型参数(超参数)的效果时,直接使用测试集将有可能存在过拟合测试集的风险(多次人为调整模型参数再用测试集验证择优,相当于让模型某种程度学习了测试集),此时在测试集上评估泛化性能就不再准确。

我们可以选择将数据集划分为训练集、验证集、测试集,在验证集上调试模型参数,但这样每个集合的样本量就会减少,在总的样本数较少时,就不太合适。

Read more »

scikit-learn 笔记 - 非监督学习

Posted on 2018-10-25 | Edited on 2019-03-14

聚类 (Clustering)

聚类是一类将数据集划分为不同簇的任务。通常同簇的样本相对不同簇间的样本相似度更高。

K-均值 (K-Means)

K-Means 聚类算法的步骤:

  1. 初始化聚类数及各聚类centroid
  2. 分配:根据离centroid的距离将样本归属到某一聚类
  3. 优化:根据聚类所属样本重新计算centroid
  4. 如此重复。
1
2
3
4
5
6
7
8
from sklearn.cluster import KMeans

# Compute k-means clustering
kmeans = KMeans(n_clusters=2)
kmeans.fit(X)

# Predict the closest cluster each sample in X belongs to.
kmeans.predict(X)

K-Means 聚类算法的局限:

Read more »
12

WeiJun

If you are depressed, you are living in the past. If you are anxious, you are living in the future. If you are at peace, you are living in the present.

13 posts
12 tags
GitHub
Creative Commons
© 2019 WeiJun
Powered by Hexo v3.7.1
|
Theme – NexT.Mist v6.4.2