migege

TensorFlow 实战 02:用 DNN 做 MNIST 手写数字识别

学一门新的语言,第一个实战例子总是打印 hello world;在机器学习领域,也有一个 hello world,那就是 MNIST 手写数字识别——当然,它可比打印字符串有意义多了。

什么是 MNIST

MNIST 是深度学习巨巨 Yann LeCun 维护的一套手写数字图像数据库,包含 60000 个训练样本和 10000 个测试样本,所有这些图像已经做过规范化及居中处理,拥有同样的固定尺寸,使用起来非常方便。下面是其中几个例子。

MNIST

我们要做什么

很明显,我们马上要开始编写第一个 TensorFlow 程序,一个有实际应用价值的深度神经网络(DNN)——虽然只有 2 个隐层,做 MNIST 手写数字识别,484 很鸡冻……

Let's do it, but how?

万事开头难,迈出第一步非常关键。为了避免陷入对无限发散的未知知识点(技能树)的恐慌,我们尽量将注意力集中在主线任务上,旁枝末节以后慢慢看,当然,楼主假设你还是会写基本的 Python 的。废话不多说,动手吧!

读取 MNIST 数据

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

input_data 封装了 MNIST 数据的下载、解析功能,read_data_sets() 返回三部分数据:55000 个训练样本 mnist.train,5000 个验证样本 mnist.validation(注意到没有,这 5000 是从原始的 60000 个训练样本上拿出来的),10000 个测试样本 mnist.test

每个样本都包含一个手写数字图像 x 和一个对应的标签 y,训练集的图像和标签可以通过 mnist.train.imagesmnist.train.labels 读取,验证集和测试集同理。图像的尺寸是 28x28 像素,每个像素值代表 [0,1] 的笔划强度,我们可以把图像数据理解为一个长度为 784 的数组,也就是一个 784 维的向量。标签的取值为 [0,9] ,表示从 0 到 9 这 10 个数字,这里我们把标签处理成 10 维 one-hot 向量以方便对应 DNN 的输出。

建立 DNN 模型

接下来我们搭建一个拥有 2 个隐层的 DNN 模型,第一层拥有 1024 个神经元,第二层拥有 625 个神经元,使用 ReLU 作为激活函数,并在输入层和隐层各层都使用 dropout 机制避免模型发生过拟合,这些概念暂时不懂也没有关系,把实验做完,不懂的再去查。

import tensorflow as tf

X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.float32, [None, 10])
p_keep_input = tf.placeholder(tf.float32)
p_keep_hidden = tf.placeholder(tf.float32)


def init_weights(shape):
    return tf.Variable(tf.random_normal(shape, stddev=0.01))


w_h = init_weights([784, 1024])
w_h2 = init_weights([1024, 625])
w_o = init_weights([625, 10])


def model(X, w_h, w_h2, w_o, p_keep_input, p_keep_hidden):
    X = tf.nn.dropout(X, p_keep_input)

    h = tf.nn.relu(tf.matmul(X, w_h))
    h = tf.nn.dropout(h, p_keep_hidden)

    h2 = tf.nn.relu(tf.matmul(h, w_h2))
    h2 = tf.nn.dropout(h2, p_keep_hidden)

    return tf.matmul(h2, w_o)


py_x = model(X, w_h, w_h2, w_o, p_keep_input, p_keep_hidden)

训练模型

为了训练模型,必须有一个指标衡量模型的好坏,这个指标就是损失(loss 或 cost),loss 越接近于 0 表明模型的输出越接近于真实的标签,我们选择最常用的交叉熵 cross-entropy 作为损失函数, RMSProp 优化算法做梯度下降

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=py_x, labels=Y))
train_op = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cost)

评估模型

我们把模型输出的标签与真实的标签进行比较,并将比较结果转换为一个取值 [0, 1] 的浮点数作为准确率指标。

predict_acc = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(py_x, 1), tf.argmax(Y, 1)), tf.float32))

接下来,我们该启动程序了:

epoch_count = 20000
batch_size = 50
keep_input = 0.8
keep_hidden = 0.75

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    step = 0
    for i in xrange(epoch_count):
        step += 1
        batch_x, batch_y = mnist.train.next_batch(batch_size)
        sess.run(train_op, feed_dict={X: batch_x, Y: batch_y, p_keep_input: keep_input, p_keep_hidden: keep_hidden})
        if step % 100 == 0:
            loss, acc = sess.run([cost, predict_acc], feed_dict={X: batch_x, Y: batch_y, p_keep_input: 1., p_keep_hidden: 1.})
            print("Epoch: {}".format(step), "\tLoss: {:.6f}".format(loss), "\tTraining Accuracy: {:.5f}".format(acc))
    print("Testing Accuracy: {:0.5f}".format(sess.run(predict_acc, feed_dict={X: mnist.test.images, Y: mnist.test.labels, p_keep_input: 1., p_keep_hidden: 1.})))

整个训练过程共 20000 步,每步使用 50 个一组的随机样本做训练,每训练 100 步输出一次训练准确率,全部训练结束后使用测试集 mnist.test 评估准确率。

我们的 DNN 模型很简单,同时也很争气,准确率大概是 98.26%,有没有感觉到一种成就感……

小提示

虽然实验做完了,结果也还算不错,但此刻我们应该冷静下来认真做一下回顾,把整篇文章中不太明白的概念整理出来,深入地去做一下理论知识学习。这里推荐一本免费的电子书:Neural Networks and Deep Learning,拿来入门非常合适。

TensorFlow 实战 01:安装 GPU 版本的开发环境 (Ubuntu)

这里将介绍如何在 Ubuntu 16.04 LTS 系统上搭建 支持 GPU 的 TensorFlow 1.4.0 开发环境。

是否需要 GPU 支持?

这取决于你有没有一块儿支持 CUDA 的 NVIDIA 显卡。如果没有,只能选择 CPU 版本。如果有,继续往下看。

安装 NVIDIA 依赖

  1. 安装 CUDA Toolkit 9.0:在 CUDA Downloads 页面选择操作系统及版本,安装类型选择deb (network),最后会给出一个下载链接和一系列的命令,类似:
    sudo dpkg -i cuda-repo-ubuntu1604_9.0.176-1_amd64.deb
    sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
    sudo apt-get update
    sudo apt-get install cuda
    
    修改 PATH 环境变量
    export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
    
    修改 LD_LIBRARY_PATH 环境变量
    export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
    
  2. 安装显卡驱动,目前最新的驱动版本是 384
    sudo apt install nvidia-384
    
    驱动安装成功后,可以使用下面的命令查看显卡状态:
    nvidia-smi
    
  3. 安装 cuDNN 7,在 cuDNN下载页面 点击 Download 并填写调查问卷后,根据自己的系统环境下载对应的安装包并安装,以下是 64 位系统的示例:
    sudo dpkg -i libcudnn7_7.0.3.11-1+cuda9.0_amd64.deb
    sudo dpkg -i libcudnn7-dev_7.0.3.11-1+cuda9.0_amd64.deb
    sudo dpkg -i libcudnn7-doc_7.0.3.11-1+cuda9.0_amd64.deb
    
  4. 安装 libcupti-dev库
    sudo apt install libcupti-dev
    
    修改 LD_LIBRARY_PATH 环境变量
    export LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH
    

安装 TensorFlow

安装预编译的包或者从源码编译都是可行的。

原生 pip 安装

python 2.7/3.n 都可以。

  1. 先安装并升级 pip
    # for Python 2.7
    sudo apt-get install python-pip python-dev
    sudo pip install -U pip setuptools
    # for Python 3.n
    sudo apt-get install python3-pip python3-dev
    sudo pip3 install -U pip setuptools
    
  2. 安装 tensorflow,根据需求只执行一条命令即可
    pip install tensorflow      # Python 2.7; CPU support (no GPU support)
    pip3 install tensorflow     # Python 3.n; CPU support (no GPU support)
    pip install tensorflow-gpu  # Python 2.7; GPU support
    pip3 install tensorflow-gpu # Python 3.n; GPU support
    

源码编译安装

  1. git 下载源码仓库,切到 r1.4 分支
    git clone https://github.com/tensorflow/tensorflow
    git checkout r1.4
    
  2. 安装 bazel
    sudo apt-get install openjdk-8-jdk
    echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
    curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
    sudo apt-get update && sudo apt-get install bazel
    
  3. 安装 TensorFlow 的 Python 依赖
    sudo apt-get install python-numpy python-dev python-pip python-wheel     # for Python 2.7
    sudo apt-get install python3-numpy python3-dev python3-pip python3-wheel # for Python 3.n
    
  4. 执行安装配置,务必注意每一步的选择
    cd tensorflow # 进入第 1 步克隆的仓库根目录
    ./configure
    Please specify the location of python. [Default is /usr/bin/python]: /usr/bin/python2.7
    Found possible Python library paths:
    /usr/local/lib/python2.7/dist-packages
    /usr/lib/python2.7/dist-packages
    Please input the desired Python library path to use.  Default is [/usr/lib/python2.7/dist-packages]
    Using python library path: /usr/local/lib/python2.7/dist-packages
    Do you wish to build TensorFlow with MKL support? [y/N]
    No MKL support will be enabled for TensorFlow
    Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native]:
    Do you wish to use jemalloc as the malloc implementation? [Y/n]
    jemalloc enabled
    Do you wish to build TensorFlow with Google Cloud Platform support? [y/N]
    No Google Cloud Platform support will be enabled for TensorFlow
    Do you wish to build TensorFlow with Hadoop File System support? [y/N]
    No Hadoop File System support will be enabled for TensorFlow
    Do you wish to build TensorFlow with the XLA just-in-time compiler (experimental)? [y/N]
    No XLA support will be enabled for TensorFlow
    Do you wish to build TensorFlow with VERBS support? [y/N]
    No VERBS support will be enabled for TensorFlow
    Do you wish to build TensorFlow with OpenCL support? [y/N]
    No OpenCL support will be enabled for TensorFlow
    Do you wish to build TensorFlow with CUDA support? [y/N] Y
    CUDA support will be enabled for TensorFlow
    Do you want to use clang as CUDA compiler? [y/N]
    nvcc will be used as CUDA compiler
    Please specify the Cuda SDK version you want to use, e.g. 7.0. [Leave empty to default to CUDA 8.0]: 9.0
    Please specify the location where CUDA 8.0 toolkit is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
    Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/bin/gcc]:
    Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 6.0]: 7
    Please specify the location where cuDNN 6 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:
    Please specify a list of comma-separated Cuda compute capabilities you want to build with.
    You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus.
    Please note that each additional compute capability significantly increases your build time and binary size. [Default is: "3.5,5.2"]: 6.1
    Do you wish to build TensorFlow with MPI support? [y/N] 
    MPI support will not be enabled for TensorFlow
    Configuration finished
    
  5. 编译生成 pip 包
    bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
    bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
    
  6. 安装生成好的 pip 包,具体的 whl 包在 /tmp/tensorflow_pkg 目录下,文件名可能略有不同
    sudo pip install /tmp/tensorflow_pkg/tensorflow-1.4.0-cp27-cp27mu-linux_x86_64.whl
    

验证一下是否装成功了

  1. 启动 Python
    $ python
    
  2. 逐行敲入下面的代码
    # Python
    import tensorflow as tf
    hello = tf.constant('Hello, TensorFlow!')
    sess = tf.Session()
    print(sess.run(hello))
    
    如果能看到下面的输出
    Hello, TensorFlow!
    
    恭喜你,安装成功了……

更多的细节

请参考详细的官方文档

  1. Installing TensorFlow on Ubuntu
  2. Installing TensorFlow from Sources
  3. NVIDIA CUDA Installation Guide for Linux
  4. NVIDIA cuDNN
  5. CUDA GPUs

使用 wget 下载 HTTP 目录

Solution

wget -r -np -nH --cut-dirs=3 -R index.html http://hostname/aaa/bbb/ccc/ddd/

Explanation

  • It will download all files and subfolders in ddd directory
  • recursively (-r)
  • not going to upper directory, like ccc/... (-np)
  • not saving files to hostname folder (-nH)
  • but to ddd omitting first 3 folders aaa, bbb, ccc (--cut-dirs=3)
  • excluding index.html files (-R index.html)

Reference

http://bmwieczorek.wordpress.com/2008/10/01/wget-recursively-download-all-files-from-certain-directory-listed-by-apache/

Via

https://stackoverflow.com/questions/23446635/how-to-download-http-directory-with-all-files-and-sub-directories-as-they-appear

北京联通烽火 HG260GS-U GPON 自行更换华为 HG8240 GPON(桥接路由拨号 + IPTV)

基本情况

设备 固件
HG260GS-U G00L 3.01
HG8240 回家查了再补上

折腾目标

  1. HG8240 替换 HG260GS-U(如果只是打算破解 HG260GS-U,可参考这个帖子
  2. HG8240 桥接路由拨号,楼主是 Netgear R6400
  3. 北京联通 IPTV 要能看,直播也要能看
  4. 楼主家没有固话,有固话可能会涉及到 SIP 或者 H264 配置

设置步骤

  1. 通过无线/有线连接 HG260GS-U 光猫,浏览器打开 http://192.168.1.1 并使用 user 账号登录后,打开 http://192.168.1.1/backupsettings.conf 把配置文件下载回来,大约 50-60kb 的样子,先复制一份做后悔药;
  2. 打开配置文件 backupsettings.conf(据说最好不要用 Windows 记事本,可能会自动添加 BOM 头造成配置文件损坏的问题。原谅楼主用的是苹果本,没有亲自试过),搜索 Telnet,把 <Enable>FALSE</Enable> 修改为 <Enable>TRUE</Enable>
    <Telnet>
    <Enable>TRUE</Enable>
    </Telnet>
    
  3. 浏览器打开 http://192.168.1.1/updatesettings.html 将改完的配置上传,光猫自动重启后,Telnet 功能已经开启;
  4. telnet 命令连接光猫,输入用户名 admin 和密码 admin 登录进去:
    telnet 192.168.1.1
    
  5. 查看 sn 并保存下来,后面会用到:
    get sn
    
  6. 打开 http://192.168.1.1状态——网络侧信息——WAN 口连接信息页面上各个端口的详细信息表格拍个照,后面需要我们手工设置到华为光猫里;
  7. 网线直连 HG8240 光猫,把电脑的有线连接 IP 修改为 192.168.100.2,子网掩码 255.255.255.0,网关 192.168.100.1
  8. 打开 http://192.168.100.1 使用用户名 telecomadmin 和密码 admintelecom 登录进去;
  9. LAN 设置里把 LAN1LAN4 都选中,点应用;
  10. 设置 TR069:在 WAN 配置里点击新建,选中使能,服务选 TR069,类型选路由,IP 获取方式选 PPPoE,用户名和密码在第 1 步得到的配置文件里,密码是用 base64 加密的,随便搜个在线工具解密就好,VLAN ID 和 802.1 优先级,按第 6 步拍的照片里对应的数字填;
  11. 设置网络:在 WAN 配置里点击新建,选中使能,服务选 INTERNET,类型选桥接,桥接类型选 PPPoE 桥接,LAN 口绑定 LAN1 到 LAN3,VLAN ID 和 802.1 优先级,按第 6 步拍的照片里对应的数字填;
  12. 没有固话的纯占位设置:在 WAN 配置里点击新建,选中使能,服务选 VOIP,类型选路由,VLAN ID 和 802.1 优先级,按第 6 步拍的照片里对应的数字填;
  13. 设置 IPTV:在 WAN 配置里点击新建,选中使能,服务选 INTERNET,类型选桥接,桥接类型选 IP 桥接,IP 获取方式选 DHCP多播 VLAN ID 一定要填,不然直播频道没法看,具体值也从第 1 步得到的配置文件里找,LAN 口绑定 LAN4,VLAN ID 和 802.1 优先级,按第 6 步拍的照片里对应的数字填;
  14. 用 telnet 命令连接光猫,输入用户名 root 和密码 admin 登录进去:
    telnet 192.168.100.1
    
  15. 设置 sn 为 HG260GS-U 的 sn:
    set sn snid <刚才保存下来的sn,输入的时候不要带这里的尖括号>
    
  16. 把光纤连接到 HG8240 上,LAN1 口用网线连接到路由器的 WAN 口;
  17. 进入路由器设置 PPPoE 拨号,拨号成功后就可以上网了;
  18. IPTV 机顶盒用网线连接到 HG8240 的 LAN4 口,敲黑板,是光猫的 LAN4 口,不是路由器的 LAN4,别弄错了;
  19. 没了,网能上,IPTV 也能看了;
  20. 哦对了,在系统工具里记得保存配置到 Flash,不然光猫重启后配置丢光光;

几条弯路

  1. HG260GS-U 的 web 管理后台,不管是用 CUAdmin 还是 fiberhomehg2x0 都已经无法登录了,修改配置文件开启隐藏账号都没有用,不用试了;
  2. HG260GS-U 广为流传的 http://192.168.1.1/logoffaccount.html 也没法打开了,不用试了;

iPhone 锁屏 WebSocket 断开后的自动重连 (JavaScript)

This is no exception either. Talk is cheap, I'll show you the code.

    var newSocket = function() {
        ws = new WebSocket(wsUri);
        ws.onopen = function(evt) {
            // send a request
            if ($('#tag').val().length > 0) {
                var req = {info: $('#tag').val()}
                ws.send(JSON.stringify(req))
            }
        }
        ws.onclose = function(evt) {
            reconnectSocket()
        }
        ws.onmessage = function(evt) {
            // do what you wanna do
        }
        ws.onerror = function(evt) {
        }
    };

    var reconnectSocket = function() {
        if (!ws || ws.readyState == WebSocket.CLOSED) {
            newSocket()
        }
    };

    $('#btn-go').click(function() {
        reconnectSocket()
        return false
    })

Go 语言 switch/case 的一个小坑

前几天竟然被 switch/case 坑了一小下,坦白讲,能掉进这个坑,纯粹是基本语法不过关,把 Go 当成 C++ 了。

下面是一个简化后的粟子,通过一个人的名字来判断我认不认识他,最初写下这段代码的期望结果是:如果 nameJohnKenny,把 i_knew_him 置为 true,表示我认识这两个人,别人(默认)不认识。熟悉 C++ 的同学一定知道我为什么这样写。

var i_knew_him bool = false
switch name {
case "John":
case "Kenny":
    i_knew_him = true
}

但我们现在写的是 Go 语言,执行结果不一样了(敲黑板

我的好朋友 John 迎面走了过来,我却假装不认识他,i_knew_him = true 根本没有执行到,因为这条表达式只属于 case "Kenny"……

正确的写法是什么样的呢?

case "John", "Kenny":
    i_knew_him  = true

详见 Go 语言规范

<全文完>

Neural Networks and Deep Learning

Key points

  • Perceptron
  • Sigmoid
  • Cost function
  • Gradient Descent / Stochastic Gradient Descent
  • Back-propagation
  • Chain rule
  • Quadratic cost
  • Cross-Entropy cost
  • Softmax + log-likelihood cost
  • Overfitting
  • Early stopping strategy
  • Hold out method
  • Regularization
  • Weight decay / L2 regularization
  • L1 regularization
  • Dropout
  • Artificially increasing the training set size
  • ...

TO BE CONTINUED

《Hadoop 大数据分析与挖掘实战》笔记

第一章 数据挖掘基础

数据探索方法

  • 数据质量分析
  • 数据特征分析

数据质量分析

(1) 缺失值分析

数据的缺失主要包括记录的缺失和记录中某个字段信息的缺失。统计分析含有缺失值的属性的个数,以及每个属性的未缺失数、缺失数与缺失率。缺失值的处理:删除存在缺失值的记录、对可能值进行插补、不处理。

(2) 异常值分析

检验数据是否有录入错误以及含有不合常理的数据。异常值是指样本中的个别值,其数值明显偏离其余的观测值。异常值也称为离群点,异常值的分析也称为离群点分析。

箱型图异常值标准:

< Q_l - 1.5IQR> Q_u + 1.5IQR

其中 IQR 是四分位间距:

IQR = Q_u - Q_l

箱型图没有对数据做任何限制性要求(如服从某种特定的分布形式)。

(3) 数据一致性分析

数据一致性是指数据的矛盾性、不相容性。

数据特征分析

数据特征分析主要包括:分布分析、对比分析、统计量分析、周期性分析、贡献度分析和相关性分析。

(1) 分布分析

  • 定量数据:对称 or 非对称、特大 or 特小的可疑值,可做出频率分布表、绘制频率分布直方图、绘制茎叶图
  • 定性数据:饼图、条形图

(2) 对比分析

把两个相互联系的指标进行对比,从数量上展示和说明研究对象规模的大小,水平的高低,速度的快慢,以及各种关系是否协调。特别适用于指标间的横纵向比较,时间序列的比较分析。

关键在于选择合适的对比标准。

(3) 统计量分析

用统计指标对定量数据进行统计描述,常从集中趋势和离中趋势两个方面进行分析。平均水平的指标是对个体集中趋势的度量,使用最广泛的是均值和中位数;反映变异程度的指标则是对个体离开平均水平的度量,使用较广泛的是标准差(方差)、四分位间距。

(4) 周期性分析

周期性分析是探索某个变量是否随着时间变化而呈现出某种周期变化趋势。时间尺度相对较长的周期性趋势有年度周期性趋势、季节性周期性趋势,相对较短的有月度周期性趋势、周度周期性趋势,甚至更短的天、小时周期性趋势。

(5) 贡献度分析

贡献度分析又称帕累托分析。原理是帕累托法则(又称 20/80 定律)。可以通过帕累托图直观呈现。

(6) 相关性分析

分析连续变量之间线性相关程度的强弱,并用适当的统计指标表示出来的过程称为相关性分析。判断两个变量是否具有线性相关关系的最直观的方法是直接绘制散点图。如果需要同时考察多个变量间的相关关系时,可利用散点图矩阵来同时绘制各变量间的散点图,从而快速发现多个变量间的主要相关性,这在进行多元线性回归时显得尤为重要。在二元变量的相关性分析过程中比较常用的有 Pearson 相关系数、Spearman 秩相关系数和判定系数。

数据预处理

  • 数据清洗
  • 数据集成
  • 数据变换
  • 数据规约

数据清洗

删除无关数据、重复数据,平滑噪音数据,筛选掉与挖掘主题无关的数据,处理缺失值、异常值。

(1) 缺失值处理

  • 删除记录
  • 插补:拉格朗日插值、牛顿插值
  • 不处理

(2) 异常值处理

分析异常值出现的可能原因,再判断异常值是否应该舍弃,如果是正确的数据,可以直接在具有异常值的数据集上进行建模。

数据集成

将多个数据源合并,在最低层上加以转换、提炼和集成。

数据变换

对数据进行规范化处理以适用于挖掘任务及算法需要。常用的变换方法有:简单函数变换、规范化、连续属性离散化、属性构造、小波变换。

(1) 简单函数变换

用来将不具有正态分布的数据变换成具有正态分布的数据;在时间序列分析中,有时简单的对数变换或差分运算可将非平稳序列转换为平稳序列。如:个人年收入的取值范围为 10000 元到 10 亿元,使用对数变换对其压缩是常用的一种变换处理。

常用:平方、开方、取对数、差分运算。

(2) 规范化

归一化处理是数据挖掘的一项基础工作。不同评价指标往往具有不同的量纲和量纲单位,数值间的差别可能很大,不进行处理可能会影响到数据分析的结果。

常用:最小-最大规范化、零均值规范化、小数定标规范化。

(3) 连续属性离散化

一些挖掘算法如 ID3、Apriori 要求数据是离散属性形式。

方法:在数据的取值范围内设定若干个离散的划分点,将取值范围划分为一些离散化的区间,最后用不同的符号或整数值代表落在每个子区间中的数据值。所以离散化涉及两个子任务:确定分类数、连续属性映射分类值。

常用的连续属性离散化方法有:等宽法、等频法、(一维)聚类。

(4) 属性构造

利用已有的属性集构造出新的属性,并加入再有的属性集中。

(5) 小波变换

新型的数据分析工具,是信号分析手段。小波变换具有多分辨率的特点,在时域和频域都具有表征信号局部特征的能力,通过伸缩和平移等运算过程对信号进行多尺度聚集分析,提供了一种非平稳信号的时频分析手段,可以由粗及细地逐步观察信号,从中提取有用信息。

数据规约

通过选择替代的、较小的数据来减小数据量,包括有参数方法和无参数方法两类。

  • 有参数方法是使用一个模型来评估数据,只需存放参数,不存放实际数据。如回归(线性回归和多元回归)和对数线性模型(近似离散属性集中的多维概率分布)。
  • 无参数方法需要存放实际数据,如直方图、聚类、抽样(采样)。

模型评价

分类与预测模型

使用测试集,通常用相对绝对误差、平均绝对误差、根均方差、相对平方根误差等指标来衡量。

聚类分析模型

仅根据样本数据本身将样本分组,组内相似性越大,组间差别越大,效果越好。

《Go 语言编程》笔记

今天花了 2.5 小时看完这本书,总体来说这本书的内容偏浅,拿来入门比较合适——当然对于我这种从不看书、只靠文档 + 实践学习语言的来说,一些基础的知识点还是有必要补补的。看书的过程简单记了下笔记,太基础的直接跳过了,只记了部分我认为比较关键的知识点。全书最核心的部分当数第四章——并发编程。

@author migege@github
@version 170622:1

语言特点

  • 并发与分布式
  • 软件工程
  • 编程哲学

基础

多返回值

func getName() (firstName, middleName, lastName, nickName string) {
    firstName = "A"
    middleName = "B"
    lastName = "C"
    nickName = "D"
    return
}

匿名函数和闭包

f := func(x, y int) int {
    return x + y
}

反射

type Bird struct {
    Name string
    LifeExpectance int
}

func main() {
    sparrow := &Bird{"Sparrow", 3}
    s := reflect.ValueOf(sparrow).Elem()
    typeOfT := s.Type()
    for i := 0; i < s.NumField(); i++ {
        f := s.Field(i)
        fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface())
    }
}

Cgo

package main

/*
#include <stdio.h>
#include <stdlib.h>
*/
import "C"
import "unsafe"

func main() {
    cstr := C.CString("Hello, world!")
    C.puts(cstr)
    C.free(unsafe.Pointer(cstr))
}

工程管理

运行

go run

构建

go build

单元测试

go test

GDB 调试

gdb xxx

调试信息为 DWARFv3,>= gdb1.7

语法

预定义常量

const (
    c0 = iota
    c1 = iota
    c2 = iota
)

枚举

const (
    Sunday = itoa
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
    numberOfDays
)

数组切片

cap()len()

goto

竟然支持 goto

defer / panic() / recover()

defer func() {
    if r := recover(); r != nil {
        // do something
    }
}

foo()

passed by value

类型都是值传递

面向对象编程

匿名组合

虚基类

type Job struct {
    Command string
    *log.Logger
}

func (job *Job) Start() {
    job.Log("starting...")
}

非侵入式接口

一个类只需要实现了接口要求的所有函数,就认为这个类实现了该接口。

接口查询

var file1 Writer = ...
if file5, ok := file1.(two.IStream); ok {
}

类型查询

switch v := arg.(type) {
    case int:
    case string:
    default:
    // ...
}

并发编程

goroutine

go 关键字

并发通信

不要通过共享内存来通信,而应该通过通信来共享内存。

channel

ch <- 1

channel 在被读取前,写入操作是阻塞的。

<- ch

channel 在被写入前,读取操作是阻塞的。

基本语法

var ch chan int
var m map[string]chan bool
ch := make(chan int)

select

select {
    case <- ch1:
    case <- ch2:
    default:
}

缓冲机制

ch := make(chan int, 1024)

即使没有读取方,写入方也可以一直往 channel 里写入,在缓冲区被填满之前都不会阻塞。

超时机制

timeout := make(chan bool, 1)
go func() {
    time.Sleep(1e9)
    timeout <- true
}

select {
    case <- ch:
    // ...
    case <- timeout:
    // timeout
}

channel 可被传递

可以用来实现 pipe。

单向 channel

var ch1 chan<- float64 // 仅写入
var ch2 <-chan int // 仅读取

关闭 channel

close(ch)

x, ok := <-ch

多核并行化

runtime.GOMAXPROCS(runtime.NumCPU())

出让时间片

runtime.Gosched()

同步

同步锁

sync.Mutexsync.RWMutex

var l sync.Mutex
func foo() {
    l.Lock()
    defer l.Unlock()
}

全局唯一性操作

var once sync.Once
once.Do(...)

sync/atomic 子包

func CompareAndSwapUint64(val *unit64, old, new uint64) (swapped bool)

网络编程

Socket 编程

Dial()


### HTTP 编程

```net/http

RPC 编程

rpc.Register()

工程管理

gofmt

godoc

开发工具

gocode

其它

libtask

PM10 和 PM2.5 双爆表

有点突破认知了。

@北京