Example #1
0
// 对文本分词
// 输入参数:
//	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)
}
Example #2
0
// 从文件中载入词典
// 可以载入多个词典文件,文件名用","分隔,排在前面的词典优先载入分词,比如
// 	"用户词典.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("词典载入完毕")
}