如何用程序给宝宝取名
写在前面
好的名字包含父母对宝宝美好寄托,程序只是根据一些规则去生成名字,由于NLP、语料等的限制,程序生成的名字只能作为参考,质量肯定达不到宝妈宝爸钻研推敲的水平,所以不用妄想全自动化生产,还是老老实实动脑比较好。
部分生成结果
关于程序
Github
https://github.com/clg456852/Baby_name
程序使用Python编写,版本2.7。程序只考虑了的双字名字。
依赖库:
- jieba
- snowNLP
- bs4
- threadpool
- zhconv
由于涉及到爬虫,如果在公司跑的话,需要设置代理。同时在 http://auth-proxy.oa.com/DevNetTempVisit.aspx 申请访问外网权限。
。
如何取个好名字
前面说了,一个好的名字,最重要的是包含父母对宝宝美好寄托。
在此之上,尽量满足意、音、形,同时中国文化的八字也是一个考虑选项。
意: 名字最重要的属性,如希望宝宝开心取“乐”、“欣”字等,个人觉得如果,如果第二个字是动词的话,或者名字是形容词,更能获得好的寓意,如“怀乐“、”欣然“。
音: 如果名字其中的一个字的韵母与姓氏发音类似,则名字读起来会比较平滑,但不能两个都是,可能会比较绕口,同时最后一个字最好是舌根音,读起来短促有力。
形: 如果姓氏是上下结构,那么名字的其他字不宜再用相同结构。
八字: 八字平衡是最好的,通过八字的异类和同类来确定八字的喜用神。其中用神用来平衡八字,而喜神是生成用神的属性。
原理
由上面的分析,程序的实现方案为:从语料(古典诗词)中获取词汇,分析词汇的意、音、八字、五格,给出最靠谱的若干的作为选择。
我整理的语料有:诗经、楚辞、唐诗300首、宋词300首、论语、全唐宋词等,有一些已经与处理过了,以‘corpus’开头。从语料中获取语句,根据一定的规则组词、分词,获取满足目标函数的名词作为潜在的名字。
这里目标函数我没有考虑名字的形,是因为这个属性属于景上添花的类型,宝妈宝爸可以挑选过程自行决定。
计算名字的八字、五格,我是用爬虫提交表单 https://www.meimingteng.com/Naming/Default.aspx?Tag=4 ,再分析返回结果。所以短时间密集发送表单,可能会被服务器封IP,需要大量爬取的话最好建个代理池。
语料 -〉 组词 -〉词组分析 -〉获取寓意、八字得分 -〉排序输出
为了满足上面的需求,采用一些现有的第三方包来实现部分功能。
其中:
snowNLP可以分析词语的词性、声母、情感分析。
jieba可以对现有的语料进行分词。
zhconv用来将繁体语料转成简体版本。
bs4用来分析爬虫爬到的结果。
threadpool利用多线程来加速爬虫请求。
使用方法
运行create_name脚本,可从语料中组词并提交表单到姓名打分网。
如果已经有名字可以直接运行name_score_post脚本,还还有其他一些是用做辅助工具的脚本。
程序结构
程序最主要的脚本有两个:‘create_name.py’ 和 ’name_score_post.py’。
- create_name
从语料中组词,挑选满足目标函数的词,输出到目标文件中。
默认从楚辞里组词,可以自行选择其他语料,全唐宋词规模太大,不推荐。
# 诗经
# create_name_from(convertZh.shi_jing)
# 楚辞
create_name_from(convertZh.chu_ci)
name_score_post.create_name_excel_from(convertZh.chu_ci)
# 300 tang
# create_name_from(convertZh.tang_300_peom)
# 300 chu
# create_name_from(convertZh.song_300_verse)
# quan tang song verse
# create_name_from(convertZh.all_tang_song_verse)
# lun_lu
# create_name_from(convertZh.lun_yu)
组词规则: 在句首、句尾、句间挑选字来组词,子句内用jieba分词去取的句内的词。
def create_names_based_on(text_line):
clauses = clauses_from_sentence(text_line)
names = []
# 子句内
for clause in clauses:
if len(clause) > 3:
add_new_name(clause[0] + clause[1], names)
add_new_name(clause[-2] + clause[-1], names)
add_new_name(clause[-3] + clause[-1], names)
seg_list = jieba.cut(clause, cut_all=True)
for seg in seg_list:
if len(seg) == 2:
add_new_name(seg, names)
if len(seg) == 4:
add_new_name(seg[0] + seg[1], names)
add_new_name(seg[-2] + seg[-1], names)
# 子句间
if len(clauses) > 1:
for i in range(len(clauses)):
if (i + 1) < len(clauses):
clause_pre = clauses[i]
clause_post = clauses[i+1]
add_new_name(clause_pre[-1] + clause_post[-1], names)
add_new_name(clause_pre[0] + clause_post[0], names)
idx0 = random.randint(0, len(clause_pre)-1)
idx1 = random.randint(0, len(clause_post)-1)
add_new_name(clause_pre[idx0] + clause_post[idx1], names)
if (i + 2) < len(clauses):
clause_pre = clauses[i]
clause_post = clauses[i + 2]
add_new_name(clause_pre[-1] + clause_post[-1], names)
add_new_name(clause_pre[0] + clause_post[0], names)
idx0 = random.randint(0, len(clause_pre)-1)
idx1 = random.randint(0, len(clause_post)-1)
add_new_name(clause_pre[idx0] + clause_post[idx1], names)
names.append(u"\n来源: " + text_line)
return names
目标函数: 基于snowNLP实现,用来挑选正向的、词性、发声满足特定规则的词汇。
s = SnowNLP(n)
if s.sentiments > 0.6:
if s.pinyin:
for py in s.pinyin:
if (py.encode('utf-8').endswith(finals_consonant) or py.encode('utf-8').endswith(finals_consonant[-1]))\
and not py.encode('utf-8').startswith(initial_consonant):
# Pin Yin
has_added = True
postive_targets.write(n.encode('utf-8') + "\n")
print(n.encode('utf-8') + '\n')
if s.tags and not has_added:
for tag in s.tags:
# 获取词性
if not has_added and ((tag[0] == n[0] and tag[1] == u'v') or tag[1] == u'a'):
has_added = True
postive_targets.write(n.encode('utf-8') + "\n")
print(n.encode('utf-8') + '\n')
if len(s.tags) > 2:
assert 0
- name_score_post
读取目标文件,利用爬虫获取姓名在&网站&的分析结果,获取姓名的文化印象、八字、五格方面的得分,输出Excel表格以供参考。
def compute_score_of_name(name):
form['ctl00$ContentPlaceHolder1$InputBasicInfo1$tbMingWords'] = name
try:
paramsData = urllib.urlencode(form)
request = urllib2.Request(url, paramsData)
# print("HTTP GET")
response = urllib2.urlopen(request, timeout=20)
# print("Respone Successfully")
content = response.read()
except Exception as e:
print("Error: " + str(e))
return None
soup = BeautifulSoup(content, 'html.parser')
# print(soup)
correct_response = False
for node in soup.find_all("table", class_="naming2"):
node_content = node.get_text()
if u"评分:" in node_content:
correct_response = True
score_culture = get_score_of("文化印象", node, soup)
score_bazi = get_score_of("五行八字", node, soup)
score_shengxiao = get_score_of("生 肖", node, soup)
score_wuge = get_score_of("五格数理", node, soup)
name_score = {
'文化印象': score_culture,
'五行八字': score_bazi,
'生 肖': score_shengxiao,
'五格数理': score_wuge
}
return name_score
# TODO: 不能处理的名字
if not correct_response:
return None
关于结果
理想很丰满,现实很骨感。
目前使用的NLP与用来爬分析结果的网站,均没有表现得很“智能”,所以生成的结果可用率不高,像“无父”、“无母”这种词都能取得很高的分……
不过以更佛系的态度看,生成的结果有一些还是能够给宝妈宝爸一些启发的。还是那句话,名字是父母给宝宝的一份礼物,还是更积极地参与进去比较好,这份经历本身也是甜蜜美丽的财产。