转载请注明出处:http://www.cnblogs.com/BYRans/
前面的文章已经介绍了一个回归和一个分类的例子。在逻辑回归模型中我们假设:
在分类问题中我们假设:
他们都是广义线性模型中的一个例子,在理解广义线性模型之前需要先理解指数分布族。
指数分布族(The Exponential Family)
如果一个分布可以用如下公式表达,那么这个分布就属于指数分布族:
公式中y是随机变量;h(x)称为基础度量值(base measure);
η称为分布的自然参数(natural parameter),也称为标准参数(canonical parameter);
T(y)称为充分统计量,通常T(y)=y;
a(η)称为对数分割函数(log partition function);
本质上是一个归一化常数,确保概率和为1。
当T(y)被固定时,a(η)、b(y)就定义了一个以η为参数的一个指数分布。我们变化η就得到这个分布的不同分布。
伯努利分布属于指数分布族。伯努利分布均值为φ,写为Bernoulli(φ),是一个二值分布,y ∈ {0, 1}。所以p(y = 1; φ) = φ; p(y = 0; φ) = 1 − φ。当我们变化φ就得到了不同均值的伯努利分布。伯努利分布表达式转化为指数分布族表达式过程如下:
其中,
再举一个高斯分布的例子,高斯分布也属于指数分布族。由高斯分布可以推导出线性模型(推导过程将在EM算法中讲解),由星型模型的假设函数可以得知,高斯分布的方差与假设函数无关,因而为了计算简便,我们设方差=1。高斯分布转化为指数分布族形式的推导过程如下:
其中
许多其他分部也属于指数分布族,例如:伯努利分布(Bernoulli)、高斯分布(Gaussian)、多项式分布(Multinomial)、泊松分布(Poisson)、伽马分布(Gamma)、指数分布(Exponential)、β分布、Dirichlet分布、Wishart分布。
构建广义线性模型(Constructing GLMs)
在分类和回归问题中,我们通过构建一个关于x的模型来预测y。这种问题可以利用广义线性模型(Generalized linear models,GMLs)来解决。构建广义线性模型我们基于三个假设,也可以理解为我们基于三个设计决策,这三个决策帮助我们构建广义线性模型:
- ,假设满足一个以为参数的指数分布。例如,给定了输入x和参数θ,那么可以构建y关于的表达式。
- 给定x,我们的目标是要确定T(y),即。大多数情况下T(y)=y,那么我们实际上要确定的是。即给定x,假设我们的目标函数是。(在逻辑回归中期望值是,因此目标函数h是φ;在线性回归中期望值是μ,而高斯分布中,因此线性回归中目标函数)。
- 假设自然参数η和x是线性相关,即假设:
假设有一个预测问题:基于特征商店促销活动、最近的广告、天气、星期几等特征x,来预测商店在任一小时内的顾客数目y。
根据概率知识可知,x、y符合泊松分布。泊松分布属于指数分布族,我们可以利用上面的3个假设,构建一个广义线性模型来进行构建预测模型。
GLMs构建最小二模型
线性回归中的优化目标y(损失函数)是由最小二乘法得到的,可以使用广义线性模型构建最小二乘模型。三个假设:
- 最小二乘法得到的目标变量y是一个连续值,我们假设给定x下y的分布符合高斯分布。假设1中的ExponentialFamily(η)就是高斯分布。
- 在高斯分布中,目标函数
- 假设:
推导过程如下:
第一步变换根据假设2:
第二步变换根据y|x; θ ∼ N(μ, σ2),高斯分布的期望值是μ
第三步根据假设1:高斯分布中
第四步根据假设3:
现在已经使用广义线性模型构建出了最小二乘模型,接下来的工作就是利用梯度下降、牛顿方法来求解θ。梯度下降、牛顿方法的内容请参考之前的讲义。
GLMs构建逻辑回归
逻辑回归可以用于解决二分类问题,而分类问题目标函数y是二值的离散值,。根据统计知识,二分类问题可以选择伯努利分布来构建模型。
在伯努利分布的指数分布族表达式中我们已知:,从而得到。
构建广义线性模型的三个假设:
- 假设符合伯努利分布,
- ,伯努利分布中
推导过程如下:
同最小二乘模型一样,接下来的工作就由梯度下降或牛顿方法来完成。
注意一下上面的推到结果,回忆一下,在逻辑回归中,我们选用Sigmoid函数。
之所以在逻辑回归中选用这个g(z)作为Sigmoid函数是由一套理论作支持的,这个理论便是广义线性模型。
本文链接:广义线性模型 - Andrew Ng机器学习公开课笔记1.6,转载请注明。
废话
生命在于折腾。
笔记本上的ubuntu系统从Vim
切换到neovim
,由于neovim暂时不支持lua特性,所以Shougo大神的neocomplete就用不了,所以改为使用YouCompleteMe。
之前不用这个插件的原因:
因为要使这个插件起作用,前前后后需要下载几百MB(win下更是超过了1GB)的东西,包括了Clang编译器,ycmd的c艹源码还有ycm本身的vim script,也就是说我安装这个插件比一个IDE的体积还大。
另外一个原因就是就是Windows下使用安装插件及其麻烦,这样的话就有可能无法保持相同体验,还不如不要算了。
现在为什么使用呢?第一句话。
编译流程
主要参考官方wiki中的这一部分Instructions for 64-bit using MinGW64 clang。
这短短的几句话忽略了大量的细节,如果是新手的话相信是很难搞得定的。所以我来细化它。
编译环境――MSYS2
MSYS2是作为MinGw的替代者出现的,它的出现可以说结束了Windows下模拟Linux环境混乱的局面,它移植来自Arch Linux中强大的包管理器:pacman。我们通过pacman来安装其它东西,比如说MinGw(目的在于提供编译WIndows本地程序的工具集),git(我们再也不需要装一个msysgit然后再装一个MinGw了)。
这是一篇较为详细的对比:Cygwin 与 MinGW/MSYS/MSYS2,如何选择?
官方对比How does MSYS2 differ from Cygwin
Cygwin的话,我的理解,它提供接口更加兼容POSIX,在win api和应用之间加了一层兼容层(cygwin1.dll,所以由Cygwin的gcc编译出来的应用程序在效率是输给MinGw)的,所以在win下编译unix下开源软件,首选是MinGw,你可以看到好多IDE(CodeBlock,QT等)其实包含了MinGW。
官网:msys2,下载对应平台的exe安装好之后,在开始菜单打开MSYS2 Shell
,你还会发现另外两个快捷方式MinGW-W64 win64 Shell
和MinGW-W64 win32 Shell
,不过现在它们还打不开。
打开之后,第一件事情就是更换pacman的源。
$ cd /etc/pacman.d
$ gvim -p mirrorlist.mingw32 mirrorlist.mingw64 mirrorlist.msys #你在文件浏览器打开这个路径然后用其它编辑器,这里只是示意而已.
然后在这三个文件最开头分别添加一行(按照上面的顺序)Server = http://mirrors.ustc.edu.cn/msys2/REPOS/MINGW/i686
Server = http://mirrors.ustc.edu.cn/msys2/REPOS/MINGW/x86_64
Server = http://mirrors.ustc.edu.cn/msys2/REPOS/MSYS2/$arch
$ pacman --needed -Sy bash pacman pacman-mirrors msys2-runtime
执行完毕之后,关闭Shell,重新打开。
$ pacman -Su #更新其它组件到最新..
# 安装以下东西..
$ pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb mingw-w64-x86_64-make tmux zsh git mingw64/mingw-w64-x86_64-cmake winpty-git
解释下,第一个是编译器,第二个是调试器,第三个工程管理工具make,后面两个是文本三巨头之二,在后来是版本管理神器,cmake
则是很受欢迎的新一代工程管理工具也是我们编译YCM需要的工具,最后一个是解决mintty
下有些工具卡死没有输出的情况的工具。
# winpty使用示例,这里直接调用python会卡死..
$ winpty python
mingw-w64相关默认安装/mingw64
下,所以在MSYS2 Shell
下默认找不到gcc命令的,你可以将相关路径添加到诸如/etc/profile
,.bashrc
和.zshrc
这样的文件中,也可以在win下面改Path变量。
但更直接的方式在打开前面提到的快捷方式MinGW-W64 win64 Shell
,注意别看错打开win32的shell了。
pacman的基本使用
# 安装新包
pacman -S <package_names|package_groups>
# 移除包
pacman -R <package_names|package_groups>
# 搜索包,支持正则搜索
pacman -Ss <name_pattern>
编译一个64位的gvim/vim
打开MinGW-W64 win64 Shell
。
VIM官网只提供了32位的程序,按照上面的wiki我们需要编译一个带有python2特性的64位vim好来验证我们是否安装成功了。
这里可以使用我的编译脚本和vim配置,从github上脱下之后,里面有一个build_vim.sh
脚本用于编译vim。
$ cd ~ && mkdir work && cd work
$ git clone https://github.com/tracyone/vim vim_conf && cd vim_conf
在执行这个脚本之前你需要,你需要编辑这个脚本最开头宏定义,里面定义诸如安装路径,python安装路径,架构等..
其中有python2,python3,ruby,lua,tcl,perl等外部接口支持,注意把不需要的接口对应的变量注释掉,否则会编译失败。
去官网下载最新python2,并加入Path变量,然后安装,然后修改下面几个变量
# python2 support
PYTHON=/e/program_files/Python27
DYNAMIC_PYTHON=yes
PYTHON_VER=27
$ ./build_vim.sh all
上面那条命令会下载vim源代码(接近800MB),并编译gvim和vim最终打开文件管理器,你只需要双击install.exe
然后再弹出的界面中输入d就能安全最后的安装了。另外,也拷贝了我的vimrc到vim安装目录下。所以首次打开时会自动安装插件,请确保网络通畅,由于需要安装较多插件(并且包含了接近200MB的YCM插件),请非常耐心等待。
编译ycmd
首先你得下载一个编译好的64位的LLVM with Clang Support
的安装包,奇怪的是官网只提供了32位的安装包,一度我想用MinGw从源代码编译一个,后来太多错误就放弃了,最后发现这个项目有提供64位的安装包ClangOnWin。
安装到你想要安装的地方,这里我安装到c:/LLVM
。
首先按照上面提到的wiki,用interlocked.hpp替换到%USERPROFILE%\vimfiles\bundle\YouCompleteMe\third_party\ycmd\cpp\BoostParts\boost\detail\interlocked.hpp
编辑%USERPROFILE%\vimfiles\bundle\YouCompleteMe\third_party\ycmd\cpp\CMakeLists.txt
,最后面添加:
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -include cmath")
add_definitions(-DBOOST_PYTHON_SOURCE)
add_definitions(-DBOOST_THREAD_BUILD_DLL)
add_definitions(-DMS_WIN64)
$ cd <root of vim installed>/vimfiles/bundle/YouCompleteMe
$ mkdir build
$ cmake -G "MSYS Makefiles" -DCMAKE_MAKE_PROGRAM=E:/msys64/mingw64/bin/mingw32-make.exe -DPATH_TO_LLVM_ROOT=C:/LLVM . E:/program_files/Vim/vimfiles/bundle/YouCompleteMe/third_party/ycmd/cpp
$ mingw32-make ycm_support_libs
至此结束,要确保正常运行,需要保证添加到Path环境变量中,在MSYS2 Shell中同样需要保证这两个路径在Path变量中,否则会出现加载模块的错误。
- Python2所在路径
- mingw64/bin路径
- llvm所在路径
也可以分别将相关的dll拷贝到YouCompleteMe/third_party/ycmd
路径下:libstdc++-6.dll
,libwinpthread-1.dll
,libclang.dll
和libgcc_s_seh-1.dll
。
使用教程和配置
使用YouCompleteMe对工程进行补全,需要为每个工程提供一个项目文件
:.ycm_extra_conf.py
,主要指定的是编译器的option,比如说连接的库,库路径,头文件路径,宏定义,编译器优化标志等等。
这里要介绍一个插件,YCM-Generator,他能根据项目中Makefiles等文件生成对应的.ycm_extra_conf.py
文件。很多时候这东西是不错的,但是某些情况还是不够灵活,比如说如果Makefile里面是交叉编译器的话,它不支持。
项目根目录下打开vim并执行:call GenYcm()
(我的配置里面的函数)。
另外一个插件ycm_simple_conf,这个插件需要编写一个xml文件,然后根据这个xml文件生成,这样的话就比较灵活点。
在每个项目的根目录下编写.ycm_simple_conf.xml
文件。
<project type="c++">
<include path="/home/local/libA/include"/>
<include path="/home/local/libB/include"/>
<include path="include"/>
<include path="build"/>
</project>
function! GenYCM()
let l:cur_dir=getcwd()
cd $VIMFILES/bundle/YCM-Generator
:silent execute ":!./config_gen.py ".l:cur_dir
if v:shell_error == 0
echom "Generate successfully!"
else
echom "Generate failed!"
endif
exec ":cd ". l:cur_dir
endfunction
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>
nnoremap <leader>jl :YcmCompleter GoToDeclaration<CR>
nnoremap <leader>jf :YcmCompleter GoToDefinition<CR>
let g:syntastic_always_populate_loc_list = 1
let g:ycm_confirm_extra_conf=0
let g:ycm_collect_identifiers_from_tag_files = 1
接下来有空把win32的编译,并研究下静态编译,打包传到github,从此在win下不再麻烦。
欢迎各位分享经验交流。
欢饮访问我的新博客:www.onetracy.com
本文链接:Windows下编译YouCompleteMe流程,转载请注明。
没有评论:
发表评论