分词
来源:互联网 发布:otg开关软件下载 编辑:程序博客网 时间:2024/03/29 06:31
Lucene中文分词 IKAnalyzer C#.Net版本
源代码下载地址:http://cn.ziddu.com/download.php?uid=Z7GemJepa7Cb4palY7KWlJiiZK6enZk%3D3
根据IKAnalyzer Java版本移植到C#。采用了Powercollection类库。
使用示例:
System.String testString = "据路透社报道,印度尼西亚社会事务部一官员星期二(29日)表示,日惹市附近当地时间27日晨5时53分发生的里氏6.2级地震已经造成至少5427人死亡,20000余人受伤,近20万人无家可归。";
//testString = teststr;
for(int k=0;k<10;k++)
testString += testString;
IKAnalyzer ika = new IKAnalyzer();
Console.WriteLine(testString.Length);
try
{
System.IO.TextReader r = new System.IO.StringReader(testString);
TokenStream ts = ika.TokenStream("TestField", r);
int m = 0;
long begin = System.DateTime.Now.Ticks;
for (Token t = ts.Next(); t != null; t = ts.Next())
{
m++;
// System.Console.Out.WriteLine(t.StartOffset() + " - " + t.EndOffset() + " = " + t.TermText());
}
int end = (int)((System.DateTime.Now.Ticks-begin)*1.0/100000);
System.Console.Out.WriteLine("/u8017/u65F6 : " + (end) + "ms"+" 分词个数:"+m+" 效率(词/秒):"+ ((int)(m*1.0f/(end)*1000)));
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.StackTrace);
}
另:IKAnalyzer和庖丁分词性能对比
版本:
IKAnalyzer2.0.2
paoding_analysis2.0.4alpha
测试环境:
Inter Core 1.8双核,1G内存,XP,Java1.6Se
结果:
对长度为96256中文分词:
IKAnalyzer:203ms 55296 单词 272394 词/秒
paoding:94ms 47104单词 501106词/秒
对长度为3008中文分词:
IKAnalyzer: 31ms 1728单词 55741词/秒
paoding:15ms 1472单词 98133词/秒
分词内容:
据路透社报道,印度尼西亚社会事务部一官员星期二(29日)表示,日惹市附近当地时间27日晨5时53分发生的里氏6.2级地震已经造成至少5427人死亡,20000余人受伤,近20万人无家可归。
分词效果:
IKAnalyzer:
1 - 4 = 路透社
1 - 2 = 路
4 - 6 = 报道
7 - 12 = 印度尼西亚
7 - 9 = 印度
10 - 12 = 西亚
12 - 14 = 社会
14 - 17 = 事务部
14 - 16 = 事务
17 - 18 = 一
18 - 20 = 官员
20 - 23 = 星期二
20 - 22 = 星期
22 - 23 = 二
24 - 27 = 29日
24 - 26 = 29
26 - 27 = 日
28 - 30 = 表示
31 - 34 = 日惹市
31 - 33 = 日惹
32 - 34 = 惹市
34 - 36 = 附近
36 - 40 = 当地时间
36 - 38 = 当地
38 - 40 = 时间
40 - 43 = 27日
40 - 42 = 27
43 - 44 = 晨
44 - 46 = 5时
44 - 45 = 5
46 - 49 = 53分
46 - 48 = 53
48 - 50 = 分发
49 - 51 = 发生
52 - 54 = 里氏
54 - 58 = 6.2级
54 - 57 = 6.2
58 - 60 = 地震
60 - 62 = 已经
62 - 64 = 造成
64 - 66 = 至少
66 - 71 = 5427人
66 - 70 = 5427
71 - 73 = 死亡
74 - 79 = 20000
79 - 81 = 余人
81 - 83 = 受伤
84 - 85 = 近
85 - 89 = 20万人
85 - 88 = 20万
85 - 87 = 20
87 - 89 = 万人
89 - 93 = 无家可归
92 - 93 = 归
paoding:
1 - 4 = 路透社
4 - 6 = 报道
7 - 9 = 印度
7 - 11 = 印度尼西
10 - 12 = 西亚
12 - 14 = 社会
14 - 16 = 事务
16 - 17 = 部
17 - 18 = 1
18 - 20 = 官员
20 - 22 = 星期
20 - 23 = 星期二
24 - 26 = 29
26 - 27 = 日
28 - 30 = 表示
31 - 33 = 日惹
33 - 34 = 市
34 - 36 = 附近
38 - 40 = 时间
36 - 40 = 当地时间
40 - 42 = 27
42 - 43 = 日
43 - 44 = 晨
44 - 45 = 5
45 - 46 = 时
46 - 48 = 53
48 - 49 = 分
49 - 51 = 发生
50 - 52 = 生的
52 - 54 = 里氏
54 - 57 = 6.2
57 - 58 = 级
58 - 60 = 地震
60 - 62 = 已经
62 - 64 = 造成
64 - 66 = 至少
66 - 70 = 5427
70 - 71 = 人
71 - 73 = 死亡
74 - 79 = 20000
79 - 81 = 余人
81 - 83 = 受伤
84 - 85 = 近
85 - 88 = 200000
88 - 89 = 人
89 - 93 = 无家可归
结论:
paoding和IK分词效果差不多,IK分词多些但速度差些。
值得研究的一些东东
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace LanSplit
...{
/**//// <summary>
/// 海量分词研究版C#接口
/// </summary>
public class HL
...{
/**//// <summary>海量分词系统初试化</summary>
/// <param name="dict"></param>
/// <returns>bool</returns>
[DllImport("LanSplit.bin", EntryPoint = "HLSplitInit")]
public static extern bool Init(string dict);
public static bool Init()
...{
return Init(null);
}
//public static bool Init(string dict)
//{
// return Init(dict);
//}
/**////<summary>海量分词系统卸载</summary>
///<paramref name=""/>
[DllImport("LanSplit.bin", EntryPoint = "HLFreeSplit")]
public static extern void Free();
/**//// <summary>打开海量分词句柄</summary>
/// <returns>uint handle</returns>
[DllImport("LanSplit.bin", EntryPoint = "HLOpenSplit")]
public static extern uint OpenSplit();
/**//// <summary>关闭海量分词句柄</summary>
/// <param name="handle"></param>
[DllImport("LanSplit.bin", EntryPoint = "HLCloseSplit")]
public static extern void CloseSplit(uint handle);
/**//// <summary>对一段字符串分词</summary>
/// <param name="handle">分词句柄</param>
/// <param name="lpText">要切分文本</param>
/// <param name="iExtraCalcFlag">分词选项</param>
/// <returns></returns>
[DllImport("LanSplit.bin", EntryPoint = "HLSplitWord")]
private static extern bool HLSplitWord(uint handle, string lpText, int iExtraCalcFlag);
public static bool SplitWord(uint handle, string text)
...{
return HLSplitWord(handle, text, 0);
}
public static bool SplitWord(uint handle, string text, SegOption option)
...{
return HLSplitWord(handle, text, (int)option);
}
public static bool SplitWord(uint handle, string text, int option)
...{
return HLSplitWord(handle, text, option);
}
/**//// <summary>获得分词结果个数</summary>
/// <param name="handle"></param>
/// <returns></returns>
[DllImport("LanSplit.bin", EntryPoint = "HLGetWordCnt")]
public static extern int GetWordCnt(uint handle);
/**//// <summary>获取指定的分词结果</summary>
/// <param name="handle"></param>
/// <param name="nIndex"></param>
/// <returns></returns>
[DllImport("LanSplit.bin")]
private static extern IntPtr HLGetWordAt(uint handle, int index);
/**//// <summary>
/// 此处为用户真正的接口,封装了把指针转化为结构的部分
/// </summary>
/// <param name="handle"></param>
/// <param name="index"></param>
/// <returns></returns>
public static Seg GetWordAt(uint handle, int index)
...{
IntPtr pWord = HLGetWordAt(handle, index);
Seg word = (Seg)Marshal.PtrToStructure(pWord, typeof(Seg));
//此处需要把高位屏蔽,否则得到的结果会出现错误。所有的词性值在0x4000000000下
word.POS = (POS)((uint)word.POS & 0x0FFFFFFF);
return word;
}
/**//// <summary>
/// 装载用户自定义词典
/// </summary>
/// <param name="dict"></param>
/// <returns></returns>
[DllImport("LanSplit.bin", EntryPoint = "HLOpenUsrDict")]
public static extern bool OpenUsrDict(string dict);
/**//// <summary>
/// 卸载用户自定义词典
/// </summary>
/// <returns></returns>
[DllImport("LanSplit.bin", EntryPoint = "HLFreeUsrDict")]
public static extern bool FreeUsrDict();
/**//// <summary>
/// 获取关键词个数
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
[DllImport("LanSplit.bin", EntryPoint = "HLGetFileKeyCnt")]
public static extern int GetKeyCnt(uint handle);
/**//// <summary>
/// 获取指定的关键词
/// </summary>
/// <param name="handle"></param>
/// <param name="index"></param>
/// <returns></returns>
[DllImport("LanSplit.bin")]
private static extern IntPtr HLGetFileKeyAt(uint handle, int index);
public static Seg GetKeyAt(uint handle, int index)
...{
IntPtr pWord = HLGetFileKeyAt(handle, index);
Seg word = (Seg)Marshal.PtrToStructure(pWord, typeof(Seg));
//此处需要把高位屏蔽,否则得到的结果会出现错误。所有的词性值在0x4000000000下
word.POS = (POS)((uint)word.POS & 0x0FFFFFFF);
return word;
}
/**//// <summary>
/// 获得语义指纹
/// </summary>
/// <param name="handle"></param>
/// <param name="rpData"></param>
/// <param name="rdwLen"></param>
/// <returns></returns>
[DllImport("LanSplit.bin")]
private static extern bool HLGetFingerM(uint handle, out IntPtr rData, out uint rLen);
/**//// <summary>
/// 获得语义指纹
/// </summary>
public static byte[] GetFingerM(uint handle)
...{
IntPtr p;
byte[] data = null;
uint len = 0;
bool flag = HLGetFingerM(handle, out p, out len);
if (flag == false || len == 0) return null;
data = new byte[len];
for (int i = 0; i < len; i++)
...{
data[i] = Marshal.ReadByte(p, i);
}
return data;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct Seg
...{
/**//// <summary>
/// 字符串
/// </summary>
public string word;
/**//// <summary>
/// 词性标志
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public POS POS;
/**//// <summary>
/// 关键词权重,如果不是关键词,权重为0
/// </summary>
public float weight;
};
/**//// <summary>
/// 常量定义部分,分词选项
/// </summary>
public enum SegOption : byte
...{
/**//// <summary>
/// 默认选项,仅仅分词
/// </summary>
DEFAULT = 0,
/**//// <summary>
/// 计算关键词附加标识
/// </summary>
KEYWORD = 0x1,
/**//// <summary>
/// 计算文章语义指纹标识
/// </summary>
FINGER = 0x2,
/**//// <summary>
/// 计算词性标识
/// </summary>
POS = 0x4,
/**//// <summary>
/// 输出面向检索的分词结果
/// </summary>
SEARCH = 0x8
};
/**//// <summary>
/// 词性定义部分
/// </summary>
public enum POS : uint
...{
D_A = 0x40000000, // 形容词 形语素
D_B = 0x20000000, // 区别词 区别语素
D_C = 0x10000000, // 连词 连语素
D_D = 0x08000000, // 副词 副语素
D_E = 0x04000000, // 叹词 叹语素
D_F = 0x02000000, // 方位词 方位语素
D_I = 0x01000000, // 成语
D_L = 0x00800000, // 习语
A_M = 0x00400000, // 数词 数语素
D_MQ = 0x00200000, // 数量词
D_N = 0x00100000, // 名词 名语素
D_O = 0x00080000, // 拟声词
D_P = 0x00040000, // 介词
A_Q = 0x00020000, //0x80020000,// 量词 量语素 一把,一次,一幅,一件,一拳 等
D_R = 0x00010000, // 代词 代语素
D_S = 0x00008000, // 处所词
D_T = 0x00004000, // 时间词
D_U = 0x00002000, // 助词 助语素
D_V = 0x00001000, // 动词 动语素
D_W = 0x00000800, // 0x80000800,//标点符号
D_X = 0x00000400, // 非语素字
D_Y = 0x00000200, // 语气词 语气语素
D_Z = 0x00000100, // 状态词
A_NR = 0x00000080, // 0x80000080,//人名
A_NS = 0x00000040, // 地名
A_NT = 0x00000020, // 机构团体
A_NX = 0x00000010, //0x80000010,// 外文字符
A_NZ = 0x00000008, // 其他专名
D_H = 0x00000004, // 前接成分
D_K = 0x00000002 // 后接成分
}
}
- 分词
- 分词
- 分词
- 分词
- 分词
- 分词
- 分词
- 分词:分词词典CIPP_JS
- lucene分词器分词
- PHP分词
- 中文分词
- 中文分词
- 中文分词
- lucene分词
- Java分词
- 分词系统
- 中文分词
- 中文分词
- Fedora 10 (64位)下firefox支持flash插件的操作步骤
- 免费的 trac wiki 和 subversion
- 软件开发未来的发展
- minixml2 C语言XML解析器
- 处理 C++ 项目中的 IntelliSense 失败:输入类实例后,不能显示其成员几成员函数问题解决
- 分词
- [编译错误]error LNK2005: xxxx already defined in atlmincrt.lib (atlinit.obj)
- 在C++中如何实现文件的读写?
- 关于爱情的一段对话
- 从Domino公式@DBLookup Web化谈如何实现通用函数
- 自定义水晶报表的显示
- 关于VS2005自带水晶报表版本的限制
- MOSS中EventHandler的使用
- 意外收获:如何将中文转成拼音