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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Java【代码分享 01】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类型文件,非必须依赖,可自行解析。

<!-- 用于解析csv文件 -->
<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>5.6.6</version>
</dependency>

2.2 源码

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

@Slf4j
@Component
public 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 下载地址 及介绍。

目录
相关文章
|
11天前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
|
17天前
|
图形学 Python
SciPy 空间数据2
凸包(Convex Hull)是计算几何中的概念,指包含给定点集的所有凸集的交集。可以通过 `ConvexHull()` 方法创建凸包。示例代码展示了如何使用 `scipy` 库和 `matplotlib` 绘制给定点集的凸包。
25 1
|
18天前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
18天前
|
数据采集 Web App开发 iOS开发
如何使用 Python 语言的正则表达式进行网页数据的爬取?
使用 Python 进行网页数据爬取的步骤包括:1. 安装必要库(requests、re、bs4);2. 发送 HTTP 请求获取网页内容;3. 使用正则表达式提取数据;4. 数据清洗和处理;5. 循环遍历多个页面。通过这些步骤,可以高效地从网页中提取所需信息。
|
21天前
|
Java
Java代码解释++i和i++的五个主要区别
本文介绍了前缀递增(++i)和后缀递增(i++)的区别。两者在独立语句中无差异,但在赋值表达式中,i++ 返回原值,++i 返回新值;在复杂表达式中计算顺序不同;在循环中虽结果相同但使用方式有别。最后通过 `Counter` 类模拟了两者的内部实现原理。
Java代码解释++i和i++的五个主要区别
|
17天前
|
索引 Python
SciPy 空间数据1
SciPy 通过 `scipy.spatial` 模块处理空间数据,如判断点是否在边界内、计算最近点等。三角测量是通过测量角度来确定目标距离的方法。多边形的三角测量可将其分解为多个三角形,用于计算面积。Delaunay 三角剖分是一种常用方法,可以对一系列点进行三角剖分。示例代码展示了如何使用 `Delaunay()` 函数创建三角形并绘制。
25 0
|
Java C语言 C++
Java 的数据类型划分(数据类型划分)| 学习笔记
快速学习 Java 的数据类型划分(数据类型划分)
122 0
Java 的数据类型划分(数据类型划分)| 学习笔记
|
Java 开发者 Windows
Java 数据类型划分(字符型)|学习笔记
快速学习 Java 数据类型划分(字符型)
127 0
|
Java 开发者
Java 数据类型划分(整型类型)|学习笔记
快速学习 Java 数据类型划分(整型类型)
|
Java 开发者
Java 数据类型划分(初见 String 类)|学习笔记
快速学习 Java 数据类型划分(初见 String 类)
下一篇
无影云桌面