> 文档中心 > 【Java代码】Java版本的NGender根据中文姓名猜测其性别及男性化/女性化程度(Python版本地址+Java版本源码+基础数据)

【Java代码】Java版本的NGender根据中文姓名猜测其性别及男性化/女性化程度(Python版本地址+Java版本源码+基础数据)

【资源链接】

链接:https://pan.baidu.com/s/1NSH5T0qkTTcOJbURd9Mq7A
提取码:nnx6

【包含文件

在这里插入图片描述

1.需求说明

由于项目需要通过姓名判断性别,在网络上找到了PythonNGender包,但项目的技术栈是Java,首先想到的是使用jython-standalone来执行 Python 代码,在 idea 成功调用,在部署时却无法找到NGender模块,最终无法解决部署问题因此有了 Java 版本的 NGender 😄 有成功部署的小伙伴儿可以分享一下经验。Java 版本说明:

  • 82%的准确率(与python版本一致)
  • 可用于猜测性别
  • 可用于判断名字的男性化/女性化程度

2.代码实现

2.1 依赖

用于解析csv类型文件,非必须依赖,可自行解析。

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.6.6</version></dependency>

2.2 源码

源码从 Python 代码转化,并未进行优化。

@Slf4j@Componentpublic class GenderUtils { private Map<String, String> genderMap = new HashMap<>(9443);    private int maleTotal = 0;    private int femaleTotal = 0;    private int genderTotal = 0;    @PostConstruct    private void init() { // 加载文件 File toFile = new File("data/ngender/charfreq.csv"); // 解析CSV文件 CsvData rows = CsvUtil.getReader().read(toFile); for (int i = 1, rowCount = rows.getRowCount(); i < rowCount; i++) {     CsvRow row = rows.getRow(i);     maleTotal += Integer.parseInt(row.get(1));     femaleTotal += Integer.parseInt(row.get(2)); } genderTotal = maleTotal + femaleTotal; // 封装对象 for (int i = 1, rowCount = rows.getRowCount(); i < rowCount; i++) {     CsvRow row = rows.getRow(i);     String nameChar = row.get(0);     int maleNum = Integer.parseInt(row.get(1));     int femaleNum = Integer.parseInt(row.get(2));     genderMap.put(nameChar, 1.0 * femaleNum / femaleTotal + "," + 1.0 * maleNum / maleTotal); }    }    /**     * 根据姓名判断性别(仅支持中文)     *     * @param nameString 姓名     * @return 性别信息     */    public Map<String, String> guessGenderByName(String nameString) { // 截取【名】的全部字符字符 char[] nameChars = nameString.substring(1).toCharArray(); // 获取性别可能性数据 double maleProb = getGenderProb(nameChars, 1); double femaleProb = getGenderProb(nameChars, 0); // 返回结果 if (maleProb > femaleProb) {     return new HashMap<String, String>(2) {{  put("male", String.valueOf(maleProb / (maleProb + femaleProb)));     }}; } else if (femaleProb > maleProb) {     return new HashMap<String, String>(2) {{  put("female", String.valueOf(femaleProb / (maleProb + femaleProb)));     }}; } else {     return new HashMap<String, String>(2) {{  put("unknown", "0");     }}; }    }    /**     * 计算性别可能性     *     * @param nameChars  【名】的全部字符字符     * @param genderFlag 0 female 1 male     * @return 性别及可能性     */    private double getGenderProb(char[] nameChars, int genderFlag) { double baseProb; if (genderFlag == 0) {     baseProb = 1.0 * femaleTotal / genderTotal; } else {     baseProb = 1.0 * maleTotal / genderTotal; } for (char nameChar : nameChars) {     baseProb *= Double.parseDouble(MapUtils.getString(genderMap, nameChar + "", "0,0").split(",")[genderFlag]); } return baseProb;    }}

2.3 调用

charfreq.csv文件有9943条,整个工具类的加载需要88ms【仅测试一次】

Map<String, String> resultMap = genderUtils.guessGenderByName("刘芳芳");// "female": "0.9835037905504539"

3.其他

Python 版本的 NGender 下载地址 及介绍。