?? simpledictseg.cs
字號:
?/***************************************************************************************
* KTDictSeg 簡介: KTDictSeg 是由KaiToo搜索開發的一款基于字典的簡單中英文分詞算法
* 主要功能: 中英文分詞,未登錄詞識別,多元歧義自動識別,全角字符識別能力
* 主要性能指標:
* 分詞準確度:90%以上(有待專家的權威評測)
* 處理速度: 600KBytes/s
*
* 版本: V1.2.02
* Copyright(c) 2007 http://www.kaitoo.com
* 作者:肖波
* 授權: 開源GPL
* 公司網站: http://www.kaitoo.com
* 個人博客: http://blog.csdn.net/eaglet; http://www.cnblogs.com/eaglet
* 聯系方式: blog.eaglet@gmail.com
* ***************************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using System.Reflection;
using FTAlgorithm;
using FTAlgorithm.General;
namespace KTDictSeg
{
/// <summary>
/// 簡單字典分詞
/// </summary>
public class CSimpleDictSeg
{
const string CHS_STOP_WORD_FILENAME = "chsstopwords.txt";
const string ENG_STOP_WORD_FILENAME = "engstopwords.txt";
IRule[] m_Rules ;
//中文停用詞哈希表
Hashtable m_ChsStopwordTbl = new Hashtable();
//英文停用詞哈希表
Hashtable m_EngStopwordTbl = new Hashtable();
CExtractWords m_ExtractWords;
const string PATTERNS = @"[0-9\d]+\%|[0-9\d]{1,2}月|[0-9\d]{1,2}日|[0-9\d]{1,4}年|"+
@"[0-9\d]{1,4}-[0-9\d]{1,2}-[0-9\d]{1,2}|" +
@"[0-9\d]+|[^a-zA-Za-zA-Z0-90-9\u4e00-\u9fa5]|[a-zA-Za-zA-Z]+|[\u4e00-\u9fa5]+";
//const string PATTERNS = @"[a-zA-Z]+|\d+|[\u4e00-\u9fa5]+";
String m_DictPath;
CPOS m_POS;
PosBinRule m_PosBinRule;
MatchName m_MatchNameRule;
/// <summary>
/// 字典
/// </summary>
T_DictFile m_Dict;
/// <summary>
/// 字典管理
/// </summary>
DictManage.DictMgr m_DictMgr = new DictManage.DictMgr();
/// <summary>
/// 未登錄詞統計字典
/// 用于統計未登錄詞的出現頻率和詞性。
/// 目前主要統計未知詞性的未登錄詞和
/// 未知姓名
/// </summary>
T_DictFile m_UnknownWordsDict ;
/// <summary>
/// 未登錄詞字典管理
/// </summary>
DictManage.DictMgr m_UnknownWordsDictMgr = new DictManage.DictMgr();
private int m_UnknownWordsThreshold = 100;
private bool m_FreqFirst = true;
bool m_AutoStudy = false;
bool m_AutoInsertUnknownWords = false;
DateTime m_LastSaveTime; //上一次保存字典和統計信息的時間
int m_AutoSaveInterval = 24 * 3600; //間隔多少秒自動保存最新的字典和統計信息,AutoStudy = true時有效
String m_LogFileName = "KTDictSeg.log";
#region Public property
/// <summary>
/// 未登錄詞閾值,當統計超過這個值時,自動將未登錄詞加入到
/// 字典中
/// </summary>
public int UnknownWordsThreshold
{
get
{
return m_UnknownWordsThreshold;
}
set
{
if (value < 1)
{
m_UnknownWordsThreshold = 1;
}
else
{
m_UnknownWordsThreshold = value;
}
}
}
/// <summary>
/// 自動插入超過統計閾值的未登錄詞
/// </summary>
public bool AutoInsertUnknownWords
{
get
{
return m_AutoInsertUnknownWords;
}
set
{
m_AutoInsertUnknownWords = value;
}
}
/// <summary>
/// 優先判斷詞頻,
/// 如果一個長的單詞由多個短的單詞組成,而長的單詞詞頻較低
/// 則忽略長的單詞。
/// 如 中央酒店的詞頻比中央和酒店的詞頻都要低,則忽略中央酒店。
/// </summary>
public bool FreqFirst
{
get
{
return m_FreqFirst;
}
set
{
m_FreqFirst = value;
if (m_FreqFirst)
{
m_ExtractWords.SelectByFreqEvent = SelectByFreq;
}
else
{
m_ExtractWords.SelectByFreqEvent = null;
}
}
}
/// <summary>
/// 自動學習
/// </summary>
public bool AutoStudy
{
get
{
return m_AutoStudy;
}
set
{
m_AutoStudy = value;
m_MatchNameRule.AutoStudy = value;
}
}
/// <summary>
/// 間隔多少秒自動保存最新的字典和統計信息,AutoStudy = true時有效
/// </summary>
public int AutoSaveInterval
{
get
{
return m_AutoSaveInterval;
}
set
{
if (value <= 1)
{
m_AutoSaveInterval = 1;
}
else
{
m_AutoSaveInterval = value;
}
}
}
/// <summary>
/// 字典文件所在路徑
/// </summary>
public String DictPath
{
get
{
return m_DictPath;
}
set
{
m_DictPath = value;
}
}
/// <summary>
/// 日志文件名
/// </summary>
public String LogFileName
{
get
{
return m_LogFileName;
}
set
{
m_LogFileName = value;
}
}
/// <summary>
/// 詞性
/// </summary>
public CPOS Pos
{
get
{
return m_POS;
}
}
#endregion
#region 配置文件
private object Convert(String In, Type destType)
{
if (destType.Equals(typeof(bool)))
{
return System.Convert.ToBoolean(In);
}
else if (destType.Equals(typeof(byte)))
{
return System.Convert.ToByte(In);
}
else if (destType.Equals(typeof(char)))
{
return System.Convert.ToChar(In);
}
else if (destType.Equals(typeof(DateTime)))
{
return System.Convert.ToDateTime(In);
}
else if (destType.Equals(typeof(decimal)))
{
return System.Convert.ToDecimal(In);
}
else if (destType.Equals(typeof(double)))
{
return System.Convert.ToDouble(In);
}
else if (destType.Equals(typeof(Int16)))
{
return System.Convert.ToInt16(In);
}
else if (destType.Equals(typeof(Int32)))
{
return System.Convert.ToInt32(In);
}
else if (destType.Equals(typeof(Int64)))
{
return System.Convert.ToInt64(In);
}
else if (destType.Equals(typeof(SByte)))
{
return System.Convert.ToSByte(In);
}
else if (destType.Equals(typeof(Single)))
{
return System.Convert.ToSingle(In);
}
else if (destType.Equals(typeof(String)))
{
return In;
}
else if (destType.Equals(typeof(UInt16)))
{
return System.Convert.ToUInt16(In);
}
else if (destType.Equals(typeof(UInt32)))
{
return System.Convert.ToUInt32(In);
}
else if (destType.Equals(typeof(UInt64)))
{
return System.Convert.ToUInt64(In);
}
else
{
throw new Exception(String.Format("Unknown type:{0}", destType.Name));
}
}
class CfgItem
{
public PropertyInfo Pi;
public String Comment;
public CfgItem(PropertyInfo pi, String comment)
{
Pi = pi;
Comment = comment;
}
}
CfgItem[] GetCfgItems()
{
CfgItem[] items = new CfgItem[9];
items[0] = new CfgItem(this.GetType().GetProperty("UnknownWordsThreshold"), "未登錄詞閾值,當統計超過這個值時,自動將未登錄詞加入到字典中");
items[1] = new CfgItem(this.GetType().GetProperty("AutoInsertUnknownWords"), "自動插入超過統計閾值的未登錄詞");
items[2] = new CfgItem(this.GetType().GetProperty("FreqFirst"), "優先判斷詞頻,如果一個長的單詞由多個短的單詞組成,而長的單詞詞頻較低則忽略長的單詞。如 中央酒店的詞頻比中央和酒店的詞頻都要低,則忽略中央酒店。");
items[3] = new CfgItem(this.GetType().GetProperty("AutoStudy"), "自動統計姓名前后綴,自動統計未登錄詞,自動統計詞頻");
items[4] = new CfgItem(this.GetType().GetProperty("AutoSaveInterval"), "間隔多少秒自動保存最新的字典和統計信息,AutoStudy = true時有效");
items[5] = new CfgItem(this.GetType().GetProperty("DictPath"), "字典文件所在路徑");
items[6] = new CfgItem(this.GetType().GetProperty("LogFileName"), "日志文件名");
items[7] = new CfgItem(this.GetType().GetProperty("MatchName"), "是否匹配漢語人名");
items[8] = new CfgItem(this.GetType().GetProperty("FilterStopWords"), "是否過濾停用詞");
return items;
}
/// <summary>
/// 從配置文件加載配置
/// </summary>
/// <param name="fileName">配置文件名</param>
public void LoadConfig(String fileName)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
try
{
doc.Load(fileName);
System.Xml.XmlNodeList list = doc.GetElementsByTagName("Item");
System.Xml.XmlAttribute itemName = null;
foreach (System.Xml.XmlNode node in list)
{
try
{
itemName = node.Attributes["Name"];
System.Xml.XmlAttribute value = node.Attributes["Value"];
if (itemName == null || value == null)
{
continue;
}
PropertyInfo pi = GetType().GetProperty(itemName.Value);
pi.SetValue(this, Convert(value.Value, pi.PropertyType), null);
}
catch (Exception e1)
{
WriteLog(String.Format("Load Item={0} fail, errmsg:{1}",
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -