异度部落格

学习是一种生活态度。

0%

今天在 Ubuntu 下面安装 GoAgent 遇到出现“the site"s security certificate is not trusted”的问题,根据提示发现是证书错误造成的,解决方法如下。

1)安装 libnss3-tools

sudo apt-get install libnss3-tools

2)导入证书

certutil -d sql:$HOME/.pki/nssdb -A -t TC -n "goagent" -i your_goagent_directory/local/CA.crt

参考资料: http://nigelzeng.iteye.com/blog/1748283

本文只适用于 python-nlpir V1.0 版本,有关 V2.0 版本详情参照项目源代码。

python-nlpir 是 NLPIR 中文分词工具的 Python 封装,利用 SWIG 完成 C++到 python 的接口转换。

项目地址:https://github.com/zhenlohuang/python-nlpir

NLPIR 汉语分词系统(又名 ICTCLAS2013),主要功能包括中文分词;词性标注;命名实体识别;用户词典功能;支持 GBK 编码、UTF8 编码、BIG5 编码。新增微博分词、新词发现与关键词提取;是当前最好的中文分词工具之一。

1、使用 SWIG 进行接口转换

SWIG 是个帮助使用 C 或者 C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。SWIG 能应用于各种不同类型的语言包括常用脚本编译语言例如 Perl, PHP, Python, Tcl, Ruby and PHP。支持语言列表中也包括非脚本编译语言,例如 C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), Java, Modula-3, OCAML 以及 R,甚至是编译器或者汇编的计划应用(Guile, MzScheme, Chicken)。SWIG 普遍应用于创建高级语言解析或汇编程序环境,用户接口,作为一种用来测试 C/C++或进行原型设计的工具。SWIG 还能够导出 XML 或 Lisp s-expressions 格式的解析树。SWIG 可以被自由使用,发布,修改用于商业或非商业中。

1)编写 interface 文件

%module NLPIR
%{
#define SWIG_FILE_WITH_INIT
#include "NLPIR.h"
%}
#define POS_MAP_NUMBER 4
#define ICT_POS_MAP_FIRST 1
#define ICT_POS_MAP_SECOND 0
#define PKU_POS_MAP_SECOND 2
#define PKU_POS_MAP_FIRST 3
#define POS_SIZE 40
#define GBK_CODE 0
#define UTF8_CODE GBK_CODE+1
#define BIG5_CODE GBK_CODE+2
#define GBK_FANTI_CODE GBK_CODE+3

bool NLPIR_Init(const char * sDataPath=0,int encode=GBK_CODE,const char*sLicenceCode=0);
bool NLPIR_Exit();
const char * NLPIR_ParagraphProcess(const char *sParagraph,int bPOStagged=1);
const result_t * NLPIR_ParagraphProcessA(const char *sParagraph,int *pResultCount,bool bUserDict=true);
int NLPIR_GetParagraphProcessAWordCount(const char *sParagraph);
void NLPIR_ParagraphProcessAW(int nCount,result_t * result);
double NLPIR_FileProcess(const char *sSourceFilename,const char *sResultFilename,int bPOStagged=1);
unsigned int NLPIR_ImportUserDict(const char *sFilename);
int NLPIR_AddUserWord(const char *sWord);//add by qp 2008.11.10
int NLPIR_SaveTheUsrDic();
int NLPIR_DelUsrWord(const char *sWord);
double NLPIR_GetUniProb(const char *sWord);
bool NLPIR_IsWord(const char *sWord);
const char * NLPIR_GetKeyWords(const char *sLine,int nMaxKeyLimit=50,bool bWeightOut=false);
const char * NLPIR_GetFileKeyWords(const char *sFilename,int nMaxKeyLimit=50,bool bWeightOut=false);
const char * NLPIR_GetNewWords(const char *sLine,int nMaxKeyLimit=50,bool bWeightOut=false);
const char * NLPIR_GetFileNewWords(const char *sFilename,int nMaxKeyLimit=50,bool bWeightOut=false);
unsigned long NLPIR_FingerPrint(const char *sLine);
int NLPIR_SetPOSmap(int nPOSmap);
bool NLPIR_NWI_Start();//New Word Indentification Start
int NLPIR_NWI_AddFile(const char *sFilename);
bool NLPIR_NWI_AddMem(const char *sText);
bool NLPIR_NWI_Complete();
const char * NLPIR_NWI_GetResult(bool bWeightOut=false);
unsigned int NLPIR_NWI_Result2UserDict();

2)接口转换

swig -c++ -python NLPIR.interface

执行完成接口转换后,将生成 NLPIR_wrap.cxx、NLPIR.py 两个文件,到目前为止已经完成了接口的转换,不过现在接口还不能使用,因为还没有编译好相应的库。

2、编写 setup.py 文件

'''
setup.py file for NLPIR
'''
from distutils.core import setup, Extension

NLPIR_module = Extension('_NLPIR',sources=['NLPIR_wrap.cxx'], libraries = ['NLPIR'])

setup(name = 'NLPIR',
version = '1.1',
author = 'Killua',
description = 'Python for NLPIR',
ext_modules = [NLPIR_module],
py_modules = ['NLPIR'],
)

3、编译代码

1)复制 libNLPIR.so 到/usr/lib 目录下

sudo cp libNLPIR.so /usr/lib

2)修改 NLPIR.h 文件

由于原来的 NLPIR.h 在 gcc 编译器中的兼容性并不好,所以需要对原来的头文件进行简单的修改。

#ifdef OS_LINUX
#define NLPIR_API
#else
#ifdef NLPIR_EXPORTS
#ifdef CSHARP_API
#define NLPIR_API extern "C" __declspec(dllexport)
#else
#define NLPIR_API __declspec(dllexport)
#endif
#else
#ifdef CSHARP_API
#define NLPIR_API extern "C" __declspec(dllimport)
#else
#define NLPIR_API __declspec(dllimport)
#endif
#endif
#endif
#if defined(NLPIR_JNI_EXPORTS)||defined(KEYEXTRACT_EXPORTS)
#define NLPIR_API
#endif

改为

#ifdef linux
#define NLPIR_API
#elif _WIN32 || _WIN64
#ifdef NLPIR_EXPORTS
#define NLPIR_API __declspec(dllexport)
#else
#define NLPIR_API __declspec(dllimport)
#endif
#endif

#ifdef OS_LINUX
class CNLPIR {
#else
class __declspec(dllexport) CNLPIR {
#endif

改为

#ifdef linux
class CNLPIR {
#else
class __declspec(dllexport) CNLPIR {
#endif

3)编译代码

python setup.py build_ext --inplace

4、编写 PyNLPIR.py

为了方便使用对生成的 NLPIR.py 进行重封装。

#!/usr/bin/env python
#coding:utf-8
'''
Created on Fri 19, 2013

@author: killua
@e-mail: [email protected]
@Decription: Python for NLPIR
'''
import NLPIR
import os

def nlpir_init(init_dir = '.', code_type = 'GBK'):
'''
Init the analyzer and prepare necessary data for NLPIR according the configure file.
'''
if code_type == 'GBK':
is_succeed = NLPIR.NLPIR_Init(init_dir, NLPIR.GBK_CODE)
elif code_type == 'UTF-8' or code_type == 'UTF8':
is_succeed = NLPIR.NLPIR_Init(init_dir, NLPIR.UTF8_CODE)
elif code_type == 'BIG5':
is_succeed = NLPIR.NLPIR_Init(init_dir, NLPIR.BIG5_CODE)
elif code_type == 'GBK_FANTI':
is_succeed = NLPIR.NLPIR_Init(init_dir, NLPIR.GBK_FANTI_CODE)
if is_succeed:
print 'NLPIR Successful.'
else:
print 'NLPIR Failed.'

def nlpir_exit():
'''
Exit the program and free all resources and destroy all working buffer used in NLPIR.
'''
return NLPIR.NLPIR_Exit()

def nlpir_import_user_dict(user_dict):
'''
Import user-defined dictionary from a text file.
'''
return NLPIR.NLPIR_ImportUserDict(user_dict)

def nlpir_paragraph_process(text, is_pos_tagged = False):
'''
Process a paragraph
'''
return NLPIR.NLPIR_ParagraphProcess(text, is_pos_tagged)

def nlpir_file_process(source_file, target_file, is_pos_tagged = False):
'''
Process a text file
'''
return NLPIR.NLPIR_FileProcess(source_file, target_file, is_pos_tagged)

def nlpir_add_user_word(word):
'''
Add a word to the user dictionary.
'''
return NLPIR.NLPIR_AddUserWord(word)

def nlpir_save_user_dict():
'''
Save the user dictionary to disk.
'''
return NLPIR.NLPIR_SaveTheUsrDic()

def nlpir_delete_user_word(word):
'''
Delete a word from the user dictionary.
'''
return NLPIR.NLPIR_DelUsrWord(word)

测试

编写 demo.py

#!/usr/bin/env python
#encoding: utf8

from PyNLPIR import *

if __name__ == '__main__':

nlpir_init('.', 'UTF-8')
print nlpir_paragraph_process(r'@ICTCLAS张华平博士 应各位ICTCLAS用户的要求,张华平博士提前发布ICTCLAS2013 版本,为了与以前工作进行大的区隔,并推广NLPIR自然语言处理与信息检索共享平台,从本版本开始,系统名称调整为NLPIR汉语分词系统。')
print
print nlpir_paragraph_process(r'“屌丝”这个嘲讽意味的代词迅速爆红,迎合了大众的心理和趣味。因为你会发现从表面符合屌丝定义的人,到和屌丝属性八竿子打不着的人,都在争相认领这一名号。当人人都在忙着确认自己的屌丝身份,并乐此不疲时,屌丝一词一定与时代的什么特征实现了合拍。“屌丝”不是阿Q,他们公然比惨并乐在其中有评论认为,“屌丝”是新时代的阿Q,两者并不完全相同。首先,阿Q是文学巨匠鲁迅一己之力创造的,而“屌丝”则是网络群体狂欢的结果,它是真正由网民集体创作的形象;另外,阿Q最重要的特征是“精神胜利法”,梦想的是“银盔银甲”,意淫的是“我手持钢鞭将你打”。', True)
nlpir_exit()

运行结果

image

常见问题

  • “Unable to find vcvarsall.bat”解决办法

参见:http://www.yidooo.net/archives/unable-to-find-vcvarsall-bat-solution.html

  • 提示找不到_NLPIR 模块提示找不到_NLPIR 模块的文件

Windows:将 NLPIR.dll copy 到 System32 下

Linux:将 libNLPIR.so copy 到/usr/lib 或者/usr/lib64 下

  • 提示 License 过期

请参考:http://ictclas.nlpir.org/newsDetail?DocId=386

Change Log

Date: 2013-11-15

  • 添加对 Window 64bit 和 Linux 64bit 的支持。
  • 对项目文件结构进行调整,将 library 文件进行分离。
  • 将 NLPIR 升级到最新版本。

感谢

Version 1.1: 感谢zzdwcm,所提供有关 Linux 64bit 的补丁。

参考资料

http://ictclas.nlpir.org/

http://www.nilday.com/nlpirictclas2013-python%E7%89%88/

https://github.com/ch0psticks/nlpir-python-win32

拼写检查

所谓拼写检查,就是在使用 Google 的时候,输入错误的时候,系统对其自动纠正,如下图所示:

image

目前有很多方法可以实现这样的技术,这里使用的是贝叶斯推断的方法。

贝叶斯推断

有关贝叶斯推断的相关理论和背景知识,可以参考<href="http://www.ruanyifeng.com/blog/2011/08/bayesian_inference_part_one.html>贝叶斯推断及其互联网应用(一):定理简介

原理

用户输入了一个单词。这时分成两种情况:拼写正确,或者拼写不正确。我们把拼写正确的情况记做 c(代表 correct),拼写错误的情况记做 w(代表 wrong)。

拼写检查,就是在发生 w 的情况下,试图推断出 c。从概率论的角度看,就是已知 w,然后在若干个备选方案中,找出可能性最大的那个 c,也就是求 P(c|w)的最大值。根据贝叶斯定理:P(c|w) = P(w|c) _ P(c) / P(w)对于所有备选的 c 来说,对应的都是同一个 w,所以它们的 P(w)是相同的,因此我们求的其实是 P(w|c) _ P(c)的最大值。

P(c)的含义是,某个正确的词的出现"概率",它可以用"频率"代替。如果我们有一个足够大的文本库,那么这个文本库中每个单词的出现频率,就相当于它的发生概率。某个词的出现频率越高,P(c)就越大。

P(w|c)的含义是,在试图拼写 c 的情况下,出现拼写错误 w 的概率。这需要统计数据的支持,但是为了简化问题,我们假设两个单词在字形上越接近,就有越可能拼错,P(w|C)就越大。举例来说,相差一个字母的拼法,就比相差两个字母的拼法,发生概率更高。你想拼写单词 hello,那么错误拼成 hallo(相差一个字母)的可能性,就比拼成 haallo 高(相差两个字母)。

所以,我们只要找到与输入单词在字形上最相近的那些词,再在其中挑出出现频率最高的一个,就能实现 P(w|c) * P(c) 的最大值。

算法

1)语料库读入

这里使用的是http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists#English语料库,该语料库是这是一个由志愿者编纂的多语言词典计划,它旨在囊括各种语言词汇的语源、读音和解释。任何人甚至无须登录就可以编辑任何字词。在源代码中使用的 wiktionary 文件,里面每一行为一个单词以及单词的频率,格式为:word:frequency。

DICTIONARY = {}

def read_words():
'''
Read bag of words from file
'''
f = open('wiktionary', 'r')
for line in f.readlines():
DICTIONARY.update({line.split(':')[0] : float(line.split(':')[1])})

2)计算相似单词

这里计算相似单词使用的是编辑距离的方法,所谓编辑距离,两个单词通过删除、交换、更改和插入四种操作中的一种,就可以让一个词变成另一个词。这里生成编辑距离为 1 的单词集

def generate_edit_distance1_words(word):
'''
Generate a set of all words that are one edit distance from word
'''
#delete a character for word
deletes = [word[1:]]
deletes += [str(word[:i] + word[i+1:]) for i in range(1, len(word))]
#change position between two character for word
transposes = [str(word[1] + word[0] + word[2:])]
transposes += [str(word[:i-1] + word[i] + word[i-1] + word[i+1:]) for i in range(2, len(word))]
#replaces one character
replaces = [str(c + word[1:]) for c in string.lowercase]
replaces += [str(word[:i] + c + word[i+1:]) for i in range(1, len(word)) for c in string.lowercase]
#insert one character
inserts = [str(c + word) for c in string.lowercase]
inserts += [str(word[:i] + c + word[i:]) for i in range(1, len(word)) for c in string.lowercase]
inserts += [str(word + c) for c in string.lowercase]

return set(deletes + transposes + replaces +inserts)

3)单词修正

根据 step 2 所得到的候选单词集,在字典中进行比较,得到概率最大作为拼写建议。

def words_filter(words):
'''
Word filter
'''
return set(word for word in words if word in DICTIONARY.keys())

def candidates(word):
'''
Get all candidates for word
'''
if word in DICTIONARY.keys():
return set([word])
else:
return words_filter([word]) | words_filter(generate_edit_distance1_words(word))

def correct(word):
'''
correct the word.
'''
candidate_words = candidates(word)
candidate_dict = {}
for item in candidate_words:
candidate_dict.setdefault(item, 0)
candidate_dict.update({item : DICTIONARY[item]})

return max(candidate_dict, key = lambda x : candidate_dict[x])

示例

python spelling_corrector.py pragramming
pragramming -> programming

完整代码

#!/usr/bin/env python

import string
import os
import sys

DICTIONARY = {}

def read_words():
'''
Read bag of words from file
'''
f = open('wiktionary', 'r')
for line in f.readlines():
DICTIONARY.update({line.split(':')[0] : float(line.split(':')[1])})

def generate_edit_distance1_words(word):
'''
Generate a set of all words that are one edit distance from word
'''
#delete a character for word
deletes = [word[1:]]
deletes += [str(word[:i] + word[i+1:]) for i in range(1, len(word))]
#change position between two character for word
transposes = [str(word[1] + word[0] + word[2:])]
transposes += [str(word[:i-1] + word[i] + word[i-1] + word[i+1:]) for i in range(2, len(word))]
#replaces one character
replaces = [str(c + word[1:]) for c in string.lowercase]
replaces += [str(word[:i] + c + word[i+1:]) for i in range(1, len(word)) for c in string.lowercase]
#insert one character
inserts = [str(c + word) for c in string.lowercase]
inserts += [str(word[:i] + c + word[i:]) for i in range(1, len(word)) for c in string.lowercase]
inserts += [str(word + c) for c in string.lowercase]

return set(deletes + transposes + replaces +inserts)

def words_filter(words):
'''
Word filter
'''
return set(word for word in words if word in DICTIONARY.keys())

def candidates(word):
'''
Get all candidates for word
'''
if word in DICTIONARY.keys():
return set([word])
else:
return words_filter([word]) | words_filter(generate_edit_distance1_words(word))

def correct(word):
'''
correct the word.
'''
candidate_words = candidates(word)
candidate_dict = {}
for item in candidate_words:
candidate_dict.setdefault(item, 0)
candidate_dict.update({item : DICTIONARY[item]})

return max(candidate_dict, key = lambda x : candidate_dict[x])

if __name__ == '__main__':
read_words()
print sys.argv[1], '->', correct(sys.argv[1])

完整代码可以参见 github:https://github.com/zhenlohuang/spelling_corrector

不足之处
拼写检查的精度很大程度依赖所使用的语料库,而且本文仅仅只是抛砖引玉,只考虑编辑距离为 1 的单词的情况。许多情况下单词的拼写错误不只一处。

参考资料

http://norvig.com/spell-correct.html

http://www.ruanyifeng.com/blog/2012/10/spelling_corrector.html

http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists#English

http://zh.wiktionary.org/zh/Wiktionary:%E9%A6%96%E9%A1%B5

PySide 是跨平台的应用程式框架 Qt 的 Python 绑定版本 。在 2009 年 8 月,PySide 首次发布。提供和 PyQt 类似的功能,并相容 API。但与 PyQt 不同处为使用 LGPL 授权。

安装命令:

sudo add-apt-repository ppa:pyside
sudo apt-get update
sudo apt-get install python-pyside

如果想只装某个模块:

sudo apt-get install python-pyside.qtgui

判断对象是否存活

1)引用计数算法(Reference Counting)
     给对象中添加一个引用计数器,每当一个地方引用它时计数器+1,;当引用失效时,计数器-1;任何时刻计数器为 0 的对象就是不可能再被使用。
    举例:Python,Flashplayer,COM
    缺陷:无法解决对象之间的循环引用问题。

2)根搜索算法 以 GC Roots 作为起点,从这些节点开始向下搜索搜索所走过的路径称为引用链(Reference Chain),当一个对象到 GC Roots 没有和任何引用链相连(也可以理解为图论中的该节点不可达),则该对象是不可用的。
    Java 中,可以作为 GC Roots 的对象包括:
    ①Stack 中(Stack Frame 的本地变量表)中的引用对象。
    ②Method Area 中的静态属性引用对象和常量引用对象。
    ③Native Method Stack 中 JNI 的引用对象。

引用

1)强引用(Strong Reference):类似“Object obj=new Object()”这类的引用,只要强引用存在 GC 就不会收回被引用的对象。
2)软引用(Soft Reference):对于软引用的对象,在系统将要发生内存溢出之前,将会把这些对象列进回收的范围,进行第二次回收。如果还没有足够的内存,就会抛出内存溢出异常。
3)弱引用(Weak Reference):被弱引用关联的对象只能保留到下一次垃圾回收发生之前。
4)虚引用(Phantom Reference):被虚引用的对象,完全不会影响其生存时间构成,也无法通过虚引用取得一个实例。虚引用的唯一目的就是在对象被 GC 回收时可以收到一个通知。

垃圾收集算法

1)标记-清除算法     首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。
    优点:简单
    缺点:效率低下,且容易产生不连续的区域
2)复制算法     将内存空间分为 Eden 和 Survivor 两块区域,当一块区域内存用完时,将存活的对象复制到另一块区域,然后把之前的区域清理掉。
    优点:简单高效,不会产生不连续的区域
    缺点:内存利用率只有 50%
3)标记-整理算法     相比标记-清除算法,在标记之后并不马上进行回收,而是将存活的对象向一端移动,然后清理掉端外内存。
4)分代收集算法     将 Java Heap 分为新生代(Younger Generation)和老年代(Tenured Generation),根据各个年代的特点采用最适合的收集算法。

JVM 运行时数据区域示意图如下所示:

image

共享数据区域:Method Area、Heap
私有数据区域:VM Stack、Native Method Stack、Program Counter Register

1)方法区(Method Area)
    用于存储已被虚拟机加载的 class 信息、常量、静态变量、即时编译后的代码等数据。
    Exception:OutOfMemoryError

2)Java 虚拟机栈(JVM Stack)
    每个方法被执行时都会创建一个 Stack Frame 用于存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法被调用直至执行完成,就对应着一个 Stack Frame 在虚拟机栈中从入栈到出栈的过程。
    Exception:StackOverflowError、OutOfMemoryError

3)本地方法区(Native Method)
    为使用 Native 方法服务的。
    Exception:StackOverflowError、OutOfMemoryError

4)Java 堆(Java Heap)
    JVM 中最大的一块区域。Java Heap 是被所有线程所共享,在 JVM 启动时创建。
    在 JVM 规范中的描述如下:The heap is the runtime data area from which memory for all class instances and arrays is allocated.

5)程序计数器(Program Counter Register)
    用于指示当前线程所执行的字节码行号指示器。
    Exception:None

6)运行时常量池(Runtime Constant Pool)
    是方法区的一部分。用于存放编译时生成的各种字面变量和常用符号
    Exception:OutOfMemoryError

public class EchoDefaultSystemEncoding
{
public static void main(String[] args)
{
String encoding = System.getProperty("file.encoding");
System.out.println("Default System Encoding:" + encoding);
}
}

OS: Ubunut 12.04

Hadoop: 1.0.4

JDK: OpenJDK 1.6

1.修改 hadoop/src/contrib/build-contrib.xml

下面添加

<property name=”eclipse.home” location=”#{你的eclipse安装目录}” />
<property name=”version” value=”1.0.4″/>

2.修改 hadoop/src/contrib/eclipse-plugin/build.xml

1)添加

<path id=”hadoop-jars”>
<fileset dir=”${hadoop.root}/”>
<include name=”hadoop-*.jar”/>
</fileset>
</path>

2)在添加

<path id=”classpath”>
<pathelement location=”${build.classes}”/>
<pathelement location=”${hadoop.root}/build/classes”/>
<!– hadoop-core-1.0.4.jar dependency –>
<pathelement location=”${hadoop.root}”/>
<!– common lib dependency –>
<pathelement location=”${hadoop.root}/lib”/>
<path refid=”eclipse-sdk-jars”/>
<path refid=”hadoop-jars”/>
</path>

3)在添加

<target name=”jar” depends=”compile” unless=”skip.contrib”>
<mkdir dir=”${build.dir}/lib”/>
<!– 将以下jar包打进hadoop-eclipse-1.0.4.jar中 –>
<copy file=”${hadoop.root}/hadoop-core-1.0.4.jar” tofile=”${build.dir}/lib/hadoop-core.jar” verbose=”true”/>
<copy file=”${hadoop.root}/lib/commons-cli-1.2.jar” todir=”${build.dir}/lib” verbose=”true”/>
<copy file=”${hadoop.root}/lib/commons-lang-2.4.jar” todir=”${build.dir}/lib” verbose=”true”/>
<copy file=”${hadoop.root}/lib/commons-configuration-1.6.jar” todir=”${build.dir}/lib” verbose=”true”/>
<copy file=”${hadoop.root}/lib/jackson-mapper-asl-1.8.8.jar” todir=”${build.dir}/lib” verbose=”true”/>
<copy file=”${hadoop.root}/lib/jackson-core-asl-1.8.8.jar” todir=”${build.dir}/lib” verbose=”true”/>
<copy file=”${hadoop.root}/lib/commons-httpclient-3.0.1.jar” todir=”${build.dir}/lib” verbose=”true”/>
<jar
jarfile=”${build.dir}/hadoop-${name}-${version}.jar”
manifest=”${root}/META-INF/MANIFEST.MF”>
<fileset dir=”${build.dir}” includes=”classes/ lib/”/>
<fileset dir=”${root}” includes=”resources/ plugin.xml”/>
</jar>
</target>

3.将 hadoop-core-1.0.4.jar 复制到 hadoop/build 目录下

4.将 hadoop/lib/commons-cli-1.2.jar 复制到 hadoop/build/ivy/lib/Hadoop/common(没有请自行创建)目录下

5.进入 hadoop/src/contrib 目录,执行 ant jar

6.将 hadoop/build/contrib/eclipse-plugin/hadoop-eclipse-plugin-1.0.4.jar 复制到 eclipse/plugins 目录下

参考资料:

http://tianwenbo.iteye.com/blog/1464242 http://blog.csdn.net/yundixiaoduo/article/details/7451753 http://hi.baidu.com/geogrex/item/4e5853ce8fd4e01f0ad93a9f#0

OS: Ubuntu 12.04   Hadoop: Hadoop 1.0.4

1.安装集群所需软件

sudo apt-get install install ssh
sudo apt-get install rsync

配置ssh免密码登录

ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
cat ~/.ssh/id_dsa.pub >>~/.ssh/authorized_keys

验证是否成功

ssh localhost

2.安装JDK

安装部分就不重复了,主要说明下环境变量的添加

sudo vi /etc/profile

将下面三句话添加到最后

export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

3.安装Hadoop

下载地址:http://apache.etoak.com/hadoop/common/ 建议选择:1.0.x版本的tar文件,不建议使用deb或者rpm的包,因为后面回带来很复杂的程序权限问题。 修改配置文件,指定JDk安装路径

vi conf/hadoop-env.sh
export JAVA_HOME=/usr/lib/jvm/java-6-openjdk

修改Hadoop核心配置文件core-site.xml,这里配置的是HDFS的地址和端口号

vi conf/core-site.xml
<pre class="brush: xml; gutter: true; first-line: 1"><configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://localhost:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/killua/Application/tmp/hadoop-${user.name}</value>
</property>
</configuration>

修改Hadoop中HDFS的配置,配置的备份方式默认为3,因为安装的是单机版,所以需要改为1 vi conf/hdfs-site.xml

<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>

修改Hadoop中MapReduce的配置文件,配置的是JobTracker的地址和端口

vi conf/mapred-site.xml
<configuration>
<property>
<name>mapred.job.tracker</name>
<value>localhost:9001</value>
</property>
</configuration>

启动Hadoop,在启动之前,需要格式化Hadoop的文件系统HDFS

bin/hadoop namenode -format
然后启动Hadoop所有服务,输入命令

bin/start-all.sh

**4.验证是否安装成功**
打开浏览器,分别输入一下网址:
http://localhost:50030 (MapReduce的Web页面)
http://localhost:50070 (HDfS的web页面)

ICTCLAS(Institute of Computing Technology,Chinese Lexical Analysis System),由中国科学院计算技术研究开发,功能包括中文分词;词性标注;命名实体识别;新词识别;同时支持用户词典;支持繁体中文;支持 gb2312、GBK、UTF8 等多种编码格式,是世界上最好的汉语词法分析器之一。 下载地址:http://ictclas.org/ictclas_download.aspx

原系统只提供了 C++和 Java 版本,为了方便广大 Pythoner,决定用 python 对其进行重新封装。目前仅支持 Linux,Windows 版本开发中。 pyictclas 模块中包含三个类:一个 PyICTCLAS 类,用于分词工具的调用;一个是 CodeType?类,用于存放各种编码的枚举类型;一个是 POSMap 类用于存放标注集枚举类型。

项目主页:http://code.google.com/p/python-ictclas/

该项目废除,新项目参考:http://www.yidooo.net/archives/nlpir-python-version.html