A detecção de gênero a partir de nomes é uma tarefa elementary em diversas aplicações de análise de dados, como segmentação de mercado, personalização de campanhas de advertising and marketing e análise demográfica. No entanto, determinar o gênero com base apenas no nome pode ser desafiador devido a variabilidades culturais, ortográficas e linguísticas. A combinação de tecnologias de Large Knowledge e Processamento de Linguagem Pure (NLP) oferece uma solução robusta para esse problema. Este artigo apresenta uma abordagem prática utilizando PySpark, bibliotecas de NLP e algoritmos de aprendizado de máquina, implementada em um ambiente de pocket book no Microsoft Material.
Além disso, a implementação eficiente da detecção de gênero pode melhorar a qualidade dos dados e fornecer insights mais precisos. A capacidade de processar grandes volumes de dados em tempo actual e aplicar técnicas avançadas de análise é essencial para lidar com a diversidade e a escala dos dados modernos. Este estudo visa demonstrar como a integração de várias ferramentas e bibliotecas pode resultar em um sistema eficaz e escalável para a detecção de gênero.
Microsoft Material
O Microsoft Material é uma plataforma de análise de dados que integra diversas ferramentas e serviços em um ambiente unificado. Ele permite a criação de pipelines de dados complexos e escaláveis, facilitando a análise e processamento de grandes volumes de dados. Utilizamos o Microsoft Material para hospedar nossos notebooks e executar tarefas de processamento de dados em grande escala com PySpark.
PySpark
PySpark é a interface Python para Apache Spark, uma ferramenta de processamento de dados em larga escala que permite a análise distribuída de grandes volumes de dados. Utilizamos PySpark para ler, transformar e manipular dados, aproveitando sua capacidade de processamento paralelo e distribuído.
Gender Guesser
Gender Guesser é uma biblioteca Python que utiliza uma base de dados de nomes comuns para prever o gênero associado a um nome específico. É rápido e eficiente, mas pode ser impreciso para nomes menos comuns ou culturalmente diversos.
NLTK (Pure Language Toolkit)
NLTK é uma biblioteca para processamento de linguagem pure. Utilizamos o NLTK como fallback quando o Gender Guesser não consegue determinar o gênero. Com ele, treinamos um classificador Naive Bayes utilizando um conjunto de dados ampliado com nomes brasileiros e dados de nomes classificados previamente.
Carregar e Normalizar os Dados para Treinamento
import pandas as pd
from pyspark.sql import SparkSession
from pyspark.sql.features import col, size
import random
import nltk
from nltk.corpus import names# Baixar os dados necessários do NLTK
nltk.obtain('names')
# Inicializar Spark Session
spark = SparkSession.builder
.appName("Gender Detection Coaching")
.getOrCreate()
# Função para normalizar os nomes, considerando apenas o primeiro nome
def normalize_first_name(identify):
first_name = identify.cut up()[0]
return first_name.capitalize()
# Carregar os dados da tabela
cliente_df = spark.learn.desk("lakehouse.base_cliente")
# Filtrar registros onde Sexo é 'F' ou 'M' para obter nomes já classificados
classified_f_df = cliente_df.filter(col("Sexo") == 'F').choose("Nome", "Sexo").drop_duplicates(["Nome", "Sexo"])
classified_m_df = cliente_df.filter(col("Sexo") == 'M').choose("Nome", "Sexo").drop_duplicates(["Nome", "Sexo"])
# Combinar ambos os DataFrames
classified_df = classified_f_df.union(classified_m_df)
# Converter o DataFrame do Spark para Pandas
classified_pd_df = classified_df.toPandas()
# Normalizar os nomes no DataFrame pandas, pegando apenas o primeiro nome
classified_pd_df['Nome'] = classified_pd_df['Nome'].apply(normalize_first_name)
classified_pd_df['Primeiro_Nome'] = classified_pd_df['Nome'].apply(lambda x: x.cut up()[0])
classified_names = listing(zip(classified_pd_df['Primeiro_Nome'], classified_pd_df['Sexo']))
import requests
# URL para a API do Brasil.io
url = 'https://knowledge.brasil.io/dataset/genero-nomes/nomes.csv.gz'
# Baixar e carregar os dados em um DataFrame
response = requests.get(url)
with open('nomes.csv.gz', 'wb') as file:
file.write(response.content material)
# Carregar a lista de nomes em um DataFrame
ibge_df = pd.read_csv('nomes.csv.gz', compression='gzip')
# Normalizar os nomes no DataFrame pandas, pegando apenas o primeiro nome
ibge_df['first_name'] = ibge_df['first_name'].apply(lambda x: x.cut up()[0].capitalize())
# Criar uma lista de tuplas (nome, sexo)
ibge_names = listing(zip(ibge_df['first_name'], ibge_df['classification']))
Caracterização com Mais Detalhes e Seleção de Características
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report# Função para caracterizar o nome com mais detalhes
def char_sexo(nome):
options = {
"primeira_letra": nome[0],
"ultima_letra": nome[-1],
"comprimento": len(nome),
"num_vogais": sum(1 for char in nome if char in "AEIOUaeiou"),
"num_consoantes": sum(1 for char in nome if char not in "AEIOUaeiou")
}
if len(nome) > 1:
options["sufixo2"] = nome[-2:]
if len(nome) > 2:
options["sufixo3"] = nome[-3:]
return options
# Lista de nomes do NLTK
nomes_nltk = ([(nome_m.split()[0].capitalize(), 'M') for nome_m in names.phrases('male.txt')] +
[(nome_f.split()[0].capitalize(), 'F') for nome_f in names.phrases('feminine.txt')])
# Combinar nomes classificados com nomes do NLTK e IBGE
nomes = nomes_nltk + classified_names + ibge_names
random.shuffle(nomes)
# Formatar dataset
dataset_formatado = [(char_sexo(n), s) for n, s in nomes]
# Separar características e labels
X, y = zip(*dataset_formatado)
# Vetorização das características
vec = DictVectorizer()
X = vec.fit_transform(X)
# Dividir o dataset em treino (90%) e teste (10%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)
# Treinar o classificador Random Forest
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.match(X_train, y_train)
# Avaliar o modelo
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred))
# Avaliar a importância das características
importances = clf.feature_importances_
feature_names = vec.get_feature_names_out()
feature_importance_df = pd.DataFrame({'function': feature_names, 'significance': importances})
feature_importance_df = feature_importance_df.sort_values(by='significance', ascending=False)
# Filtrar características importantes (exemplo: mantendo apenas as características com importância > 0.001)
important_features = feature_importance_df[feature_importance_df['importance'] > 0.001]['feature'].tolist()
# Re-treinar o modelo apenas com características importantes
important_indices = [vec.get_feature_names_out().tolist().index(feature) for feature in important_features]
X_train_important = X_train[:, important_indices]
X_test_important = X_test[:, important_indices]
clf_important = RandomForestClassifier(n_estimators=100, random_state=42)
clf_important.match(X_train_important, y_train)
# Avaliar o modelo com características importantes
y_pred_important = clf_important.predict(X_test_important)
print("Avaliação do modelo com características importantes:")
print(classification_report(y_test, y_pred_important))
# Mostrar resultados
for options, predicted, precise in zip(X_test_important, y_pred_important, y_test):
feature_dict = {vec.feature_names_[i]: options[i] for i in important_indices}
nome = feature_dict.get('primeira_letra', '') + feature_dict.get('ultima_letra', '')
print(f"{nome:<20} {predicted:<10} {precise:<10}")
Previsão de Gênero com Características Selecionadas
import gender_guesser.detector as gender# Carregar os dados onde o gênero é desconhecido
to_fix_df = cliente_df.filter(col("Sexo").isNull() & (size(col("cod")) == 11)).choose("cod", "Nome").drop_duplicates(["cod"])
# Converter o DataFrame do Spark para Pandas
to_fix_pd_df = to_fix_df.toPandas()
print(f"Nomes a corrigir: {len(to_fix_pd_df)}")
# Normalizar os nomes no DataFrame pandas, pegando apenas o primeiro nome
to_fix_pd_df['Nome'] = to_fix_pd_df['Nome'].apply(normalize_first_name)
# Função para detectar gênero utilizando gender_guesser e Random Forest como fallback
def detect_gender(identify):
d = gender.Detector()
first_name = identify.cut up()[0]
g = d.get_gender(first_name)
if g in ['male', 'mostly_male']:
return 'M'
elif g in ['female', 'mostly_female']:
return 'F'
else:
# Fallback utilizando o modelo Random Forest com características importantes
options = char_sexo(first_name)
features_vectorized = vec.rework(options)
features_vectorized_important = features_vectorized[:, important_indices]
return clf_important.predict(features_vectorized_important)[0]
# Aplicar a detecção de gênero
to_fix_pd_df['Sexo'] = to_fix_pd_df['Nome'].apply(detect_gender)
# Converter o DataFrame do Pandas de volta para o Spark
updated_to_fix_df = spark.createDataFrame(to_fix_pd_df)
# Registrar a tabela temporária
updated_to_fix_df.createOrReplaceTempView("to_fix_temp")
# Mostrar resultados atualizados
updated_to_fix_df.present()
# Executar a question de atualização
spark.sql("""
MERGE INTO lakehouse.base_cliente AS cli
USING to_fix_temp AS tf
ON cli.cod = tf.cod
WHEN MATCHED THEN
UPDATE SET cli.Sexo = cod.Sexo
""")
Treinamento do Modelo:
- Carregar dados classificados.
- Normalizar nomes.
- Caracterizar nomes com mais detalhes.
- Avaliar a importância das características e selecionar apenas as mais importantes.
- Treinar e avaliar o modelo com características importantes.
Previsão de Gênero:
- Carregar dados a serem previstos.
- Normalizar nomes.
- Prever gênero utilizando
gender_guesser
e o modelo Random Forest com características selecionadas.
Após aplicar a função de detecção de gênero, os resultados foram integrados de volta ao DataFrame do Spark e a tabela unique foi atualizada. A precisão do classificador foi satisfatória, com a maioria dos nomes sendo corretamente classificados. Abaixo, apresentamos alguns exemplos fictícios para ilustrar os resultados:
- Nome: “João Silva”, Gênero Detectado: “M”
- Nome: “Maria Souza”, Gênero Detectado: “F”
- Nome: “Alex Santos”, Gênero Detectado: “M”
- Nome: “Patrícia Lima”, Gênero Detectado: “F”
Os resultados mostram que a combinação de diferentes abordagens de detecção de gênero pode proporcionar uma classificação precisa e confiável, mesmo em bases de dados grandes e diversificadas.
A detecção de gênero a partir de nomes é uma tarefa complexa que pode ser abordada com sucesso utilizando uma combinação de bibliotecas de NLP e técnicas de aprendizado de máquina. A integração com PySpark no Microsoft Material proporciona uma solução escalável e eficiente para processar grandes volumes de dados. Este estudo demonstrou a viabilidade e eficácia da abordagem, oferecendo uma ferramenta valiosa para a análise de dados demográficos.
A capacidade de preencher automaticamente campos de gênero ausentes em bases de dados de clientes pode melhorar significativamente a qualidade das análises e a precisão das segmentações de mercado, permitindo que as empresas tomem decisões mais informadas e eficazes. A abordagem descrita neste artigo pode ser adaptada e expandida para outros contextos e tipos de dados, proporcionando uma solução versátil e poderosa para desafios semelhantes em análise de dados.
1. Documentação do Microsoft Fabric
2. Documentação do PySpark
3. Gender Guesser
4. NLTK (Natural Language Toolkit)
5. Brasil.io — Dataset de Gênero de Nomes