学习机器学习的体会与姓名性别预测案例分析
机器学习是一门关于如何从数据中自动学习规律的科学。从最初接触理论到动手实践,我逐步认识到:“算法本身不是目的,提取合适的特征 + 正确选择模型才是关键。”这篇文章将结合一个姓名性别识别的实战案例,回顾我目前学到的机器学习核心知识,并分析其中的算法应用逻辑。
案例背景:基于姓名的性别预测
我从一个 Excel 表格中读取了两张学生名单:一张为“男生名单”,一张为“女生名单”。我们希望通过分析姓名中常见字的特征,训练模型来预测新姓名的性别。
数据预处理步骤如下:
-
读取数据:使用
xlrd
库读取 Excel 表中第4列的姓名信息,分别整理为“男生姓名”和“女生姓名”两个列表。 -
构建特征:
-
female_features1
: 女字旁(如“娜”、“娇”) -
female_features2
: 常见女性名词(如“慧”、“敏”) -
male_features
: 男性偏好用字(如“勇”、“雄”)
-
-
统计特征:对每个姓名,分别统计上述特征的出现次数,共生成 3 个数值型特征。
-
添加标签:男为“男”,女为“女”。
-
输出结果:最终生成一个 CSV 文件,包含:姓名、女性特征1、女性特征2、男性特征、性别。
这一步将非结构化的“姓名”转换成了结构化的、可供机器学习使用的数据集。
可应用的机器学习模型
这类问题本质上是一个二分类问题,即根据字符统计特征,判断性别。学习过的多种分类模型都可以应用于此,包括:
1. 逻辑回归(Logistic Regression)
适合处理线性可分的二分类问题,它输出的是某类别的概率。
👉 用于此案例时,可以直接用 特征数量
(如女字旁次数)作为输入,预测概率属于“女”类别,再设定阈值(如 0.5)做判断。
2. K近邻算法(KNN)
通过比较“新姓名”与“训练集中姓名”在特征空间的“邻近度”来分类。
👉 如果一个姓名的特征向量与女性姓名更接近,则预测为“女”。
3. 朴素贝叶斯(Naive Bayes)
基于特征之间的条件独立性假设,使用概率模型做出预测,适合离散特征。
👉 如果某字符特征频繁出现在女性姓名中,就会在概率上偏向女性。
模型训练步骤梳理
将姓名特征数据输入模型后,训练流程一般如下:
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import pandas as pddata = pd.read_csv('姓名性别特征.csv')
X = data[['女性特征1','女性特征2','男性特征']]
y = data['性别'].map({'男':0,'女':1})X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)model = LogisticRegression()
model.fit(X_train, y_train)print("模型准确率:", model.score(X_test, y_test))
学习收获与总结
-
特征工程是机器学习的灵魂:哪怕是名字这样“不规则”的信息,只要设计好特征,也能转化为数值进行建模。
-
监督模型多样且有各自适用范围:逻辑回归适合线性分类,KNN适合少量样本的近似判断,朴素贝叶斯适合统计性强的特征分布。
-
无监督方法可做探索性分析:即使没有标签,也能通过聚类方式探索数据潜在结构。
-
数据清洗与编码同样重要:如标签“男”“女”要统一成数字标签,便于模型计算。
代码
importsys
fromxlrdimportopen_workbook
importxlwt
importcsv
importcodecs
defextract_features(names,female_features1,female_features2,male_features):
"""
提取姓名的性别特征
:paramnames:姓名列表
:paramfemale_features1:女性特征1列表
:paramfemale_features2:女性特征2列表
:parammale_features:男性特征列表
:return:特征列表
"""
features=[]
fornameinnames:
ifnotname:#跳过空名字
continue
feature=[name]
#计算女性特征1出现次数
f1_count=sum([1forcharinnameifcharinfemale_features1])
feature.append(f1_count)
#计算女性特征2出现次数
f2_count=sum([1forcharinnameifcharinfemale_features2])
feature.append(f2_count)
#计算男性特征出现次数
m_count=sum([1forcharinnameifcharinmale_features])
feature.append(m_count)
features.append(feature)
returnfeatures
defwrite_to_csv(data,filename,headers):
"""
将数据写入CSV文件
:paramdata:要写入的数据
:paramfilename:文件名
:paramheaders:表头
"""
withopen(filename,'w',newline='',encoding='utf-8')asf:
f_csv=csv.writer(f)
f_csv.writerow(headers)
f_csv.writerows(data)
defmain():
#读取Excel文件
workbook=open_workbook(r'学生名单.xls')
#读取男生名单
male_sheet=workbook.sheet_by_name('男')
male_names=male_sheet.col_values(3)#第4列内容
male_names=[namefornameinmale_namesifname]#过滤空值
#读取女生名单
female_sheet=workbook.sheet_by_name('女')
female_names=female_sheet.col_values(3)#第4列内容
female_names=[namefornameinfemale_namesifname]#过滤空值
#性别特征定义
female_features1=["娟","姗","婷","娜","妃","娇","嫔"]#女字旁
female_features2=["秀","美","慧","馨","敏","淑","静","洁","玲"]#其他女性特征
male_features=["勇","胜","雄"]#男性特征
#提取特征
male_features_data=extract_features(male_names,female_features1,female_features2,
male_features)
female_features_data=extract_features(female_names,female_features1,female_features2,
male_features)
#合并数据并添加性别标签
all_data=[]
fordatainmale_features_data:
data.append('男')#添加性别标签
all_data.append(data)
fordatainfemale_features_data:
data.append('女')#添加性别标签
all_data.append(data)
#写入CSV文件
headers=['姓名','女性特征1','女性特征2','男性特征','性别']
write_to_csv(all_data,'姓名性别特征.csv',headers)
print("特征提取完成,结果已保存到姓名性别特征.csv")
if__name__=='__main__':