基于古诗词的名字生成器

数据集

因为数据量庞大,使用本地的 CSV 数据进行测试。

后续改进 CSV 文件保存到 mongodb 数据库,便于聚合查询。

数据分词

我们需要一个分词器将这些数据进行分词,用到的是 Golang 版的 jieba 库如下:

"github.com/go-ego/gse"

最理想的分词器是将长短句中的名词进行提取,本 demo 使用自带的分词器。根据官方示例进行数据分词:

package util

import (
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"

	"github.com/go-ego/gse"
	"github.com/go-ego/gse/hmm/idf"
	"github.com/go-ego/gse/hmm/pos"
)

var (
	seg    gse.Segmenter
	posSeg pos.Segmenter

)

// 分词库初始化
func init() {
	// Loading the default dictionary
	err := seg.LoadDict()

	// Loading the default dictionary with embed
	//err := seg.LoadDictEmbed()

	// Loading the traditional chinese dictionary
	//err := seg.LoadDict("zh_t")

	// 加载停用词
	//err := seg.LoadDict("../data/stopwords/baidu_stopwords.txt")
	//err := seg.LoadDict("../data/stopwords/cn_stopwords.txt")
	//err := seg.LoadDict("../data/stopwords/hit_stopwords.txt")
	//err := seg.LoadDict("../data/stopwords/scu_stopwords.txt")
	if err != nil {
		log.Println(err)
		return
	}
}

func GetName(t string) {

	//cut := seg.Cut(t)
	cut := seg.CutSearch(t, true)
	cut = seg.Trim(cut)
	fmt.Println("cut all: ", cut)
	saveAsFile("NameArray.txt", cut)
}

func saveAsFile(fileName string, data []string) {

	fp, _ := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModeAppend|os.ModePerm) // 读写方式打开

	defer fp.Close()

	for _, v := range data {
		fp.WriteString(v + "\n")
	}
}

以上代码包括的官方示例和根据示例进行数据的分词,将分词结果保存为 txt 文件:

以回车符为标志,保存分词结果,是为了后续能够随机地取单词,通过行数的随机数生成,就可以随机读取单词,达到随机取词效果。

随机参数

根据时间种子进行随机数生成,返回十个随机单词:

package util

import (
	"bufio"
	"io"
	"log"
	"math/rand"
	"os"
	"time"
)

func GenerateName() {
	// 时间戳作为随机种子
	rand.Seed(time.Now().Unix())
	//getNameFile("../test/NameArray.txt")
	for i := 0; ; {
		random := rand.Intn(16497)
		name := ReadLine("../test/NameArray.txt", random, 3*2)
		if len(name) > 0 {
			log.Println(name)
			i++
			if i > 10 {
				break
			}
		}

	}
}

func ReadLine(fileName string, lineNumber, length int) string {
	file, _ := os.Open(fileName)
	fileScanner := bufio.NewScanner(file)
	lineCount := 1
	for fileScanner.Scan() {
		if lineCount == lineNumber {
			name := fileScanner.Text()
			if len(name) == length {
				return name
			} else {
				//log.Println(fileScanner.Text(), len(fileScanner.Text()), length)
				return ""
			}
			break
		}
		lineCount++
	}
	defer file.Close()
	return ""
}

func getNameFile(fileName string) {

	fp, e := os.OpenFile(fileName, os.O_RDONLY, 0644)
	if e != nil {
		log.Println(e)
	}

	defer fp.Close()

	//读入缓存
	buff := bufio.NewReader(fp)
	for {
		//以'\n'为结束符读入一行
		line, e := buff.ReadString('\n')
		if e != nil || io.EOF == e {
			log.Println(e)
			break
		}
		log.Println(line)
	}
}

2022/05/04 17:17:40 绿波
2022/05/04 17:17:40 吹愁
2022/05/04 17:17:40 出于
2022/05/04 17:17:40 城中
2022/05/04 17:17:40 江山
2022/05/04 17:17:40 九十
2022/05/04 17:17:40 天涯
2022/05/04 17:17:40 燕尾
2022/05/04 17:17:40 草色
2022/05/04 17:17:40 绿水
2022/05/04 17:17:40 心上

由输出结果可见,分词结果和随机参数效果并不是很好,需要后续改进。

分词改进

func GetName(t string) {

	po := seg.Pos(t, true)
	//fmt.Println("pos: ", po)

	po = seg.TrimWithPos(po, "zg", "x", "v", "i", "c", "r", "l")
	//po = seg.TrimWithPos(po, "zg", "x", "v")
	//fmt.Println("trim pos: ", po)

	var cut []string
	for _, v := range po {
		if len(v.Text) > 6 {
			//log.Println(v.Text, v.Pos)
		} else {
			log.Println(v.Text, v.Pos)
			cut = append(cut, v.Text)
		}
	}

	//cut := seg.Cut(t)
	//cut := seg.CutSearch(t, true)
	//cut = seg.Trim(cut)
	//fmt.Println("cut all: ", cut)

	saveAsFile("NameArray.txt", cut)

}

使用 TrimWithPos 剔除一些特殊的词语,尽量保留名词,效果如下:

  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余衫马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值