// 对文本分词 // 输入参数: // bytes UTF8文本的字节数组 // 输出: // []Segment 划分的分词 func (self *ChinaCut) Cut(bytes []byte, model bool) []search.Segment { // 处理特殊情况 if len(bytes) == 0 { return []search.Segment{} } // 划分字元 text := search.SplitTextToWords(bytes) return self.segmentWords(text, model) }
// 从文件中载入词典 // 可以载入多个词典文件,文件名用","分隔,排在前面的词典优先载入分词,比如 // "用户词典.txt,通用词典.txt" // 当一个分词既出现在用户词典也出现在通用词典中,则优先使用用户词典。 // 词典的格式为(每个分词一行): // 分词文本 频率 词性 func (self *ChinaCut) LoadDictionary(files string) { self.dict = new(search.Dictionary) for _, file := range strings.Split(files, ",") { log.Printf("载入 %s 词典", file) dictFile, err := os.Open(file) defer dictFile.Close() if err != nil { log.Fatalf("无法载入字典文件 \"%s\" \n", file) } reader := bufio.NewReader(dictFile) //词 var text string //词频字符串 var freqText string //词频int var frequency int //词性 var pos string // 逐行读入分词 for { size, _ := fmt.Fscanln(reader, &text, &freqText, &pos) if size == 0 { // 文件结束 break } else if size < 2 { // 无效行 continue } else if size == 2 { // 没有词性标注时设为空字符串 pos = "" } // 解析词频 var err error frequency, err = strconv.Atoi(freqText) if err != nil { continue } // 过滤频率太小的词 if frequency < MinTokenFrequency { continue } // 将分词添加到字典中 words := search.SplitTextToWords([]byte(text)) token := search.Token{TextList: words, Frequency: frequency, Pos: pos} self.dict.AddToken(&token) } } // 计算每个分词的路径值,路径值含义见Token结构体的注释 logTotalFrequency := float32(math.Log2(float64(self.dict.TotalFrequency))) for _, token := range self.dict.Tokens { token.Distance = logTotalFrequency - float32(math.Log2(float64(token.Frequency))) } // 对每个分词进行细致划分,用于搜索引擎模式,该模式用法见Token结构体的注释。 for _, token := range self.dict.Tokens { segments := self.segmentWords(token.TextList, true) // 计算需要添加的子分词数目 numTokensToAdd := 0 for iToken := 0; iToken < len(segments); iToken++ { if len(segments[iToken].Token.TextList) > 1 { // 略去字元长度为一的分词 // TODO: 这值得进一步推敲,特别是当字典中有英文复合词的时候 numTokensToAdd++ } } token.Segments = make([]*search.Segment, numTokensToAdd) // 添加子分词 iSegmentsToAdd := 0 for iToken := 0; iToken < len(segments); iToken++ { if len(segments[iToken].Token.TextList) > 1 { token.Segments[iSegmentsToAdd] = &segments[iToken] iSegmentsToAdd++ } } } log.Println("词典载入完毕") }