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

目录
相关文章
|
1月前
|
数据采集 数据可视化 数据挖掘
利用Python自动化处理Excel数据:从基础到进阶####
本文旨在为读者提供一个全面的指南,通过Python编程语言实现Excel数据的自动化处理。无论你是初学者还是有经验的开发者,本文都将帮助你掌握Pandas和openpyxl这两个强大的库,从而提升数据处理的效率和准确性。我们将从环境设置开始,逐步深入到数据读取、清洗、分析和可视化等各个环节,最终实现一个实际的自动化项目案例。 ####
113 10
|
12天前
|
数据采集 Web App开发 监控
Python爬虫:爱奇艺榜单数据的实时监控
Python爬虫:爱奇艺榜单数据的实时监控
|
15天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
41 3
|
23天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
57 2
|
1月前
|
数据采集 分布式计算 大数据
构建高效的数据管道:使用Python进行ETL任务
在数据驱动的世界中,高效地处理和移动数据是至关重要的。本文将引导你通过一个实际的Python ETL(提取、转换、加载)项目,从概念到实现。我们将探索如何设计一个灵活且可扩展的数据管道,确保数据的准确性和完整性。无论你是数据工程师、分析师还是任何对数据处理感兴趣的人,这篇文章都将成为你工具箱中的宝贵资源。
|
1月前
|
安全 Java API
Java中的Lambda表达式:简化代码的现代魔法
在Java 8的发布中,Lambda表达式的引入无疑是一场编程范式的革命。它不仅让代码变得更加简洁,还使得函数式编程在Java中成为可能。本文将深入探讨Lambda表达式如何改变我们编写和维护Java代码的方式,以及它是如何提升我们编码效率的。
|
3天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
34 17
|
13天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
15天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
15天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。