3、用户基础属性:性别、年龄、地域分布的数据获取与清洗,常见数据质量问题处理

聊到用户画像,大家最先想到的肯定是性别、年龄、地域这三板斧。说实话,这三项数据看着简单,但真正动手处理过的人都知道——坑多着呢。我最早做微信生态数据分析时,就栽过跟头,拿到的数据里性别字段全是「未知」,年龄分布集中在「0-18岁」,地域直接显示「海外」。嗯,今天咱们就把这些坑一个个填平。

3.1 数据获取:从哪里来,怎么拿

微信生态里,用户基础属性的获取渠道其实挺明确的。我习惯把它们分成三类:

  • 微信开放平台接口:通过 OAuth2.0 授权,能拿到用户的昵称、头像、性别、城市信息。注意,这里只能拿到「城市」级别,拿不到精确地址。
  • 公众号后台数据:用户管理模块里,能看到粉丝的性别、语言、所在地区。但有个限制——只有关注了你的公众号,你才能看到这些。
  • 小程序数据分析:微信提供「用户画像」功能,能看性别、年龄、地域的分布比例,但拿不到具体每个用户的明细数据。
我的经验: 如果你做的是小程序,建议优先用「微信开放平台」的接口。因为公众号后台的数据有滞后性,而且只能看整体分布,没法做精细化分析。我曾经为了省事直接导公众号后台数据,结果发现用户画像和实际投放效果对不上,折腾了两天才找到原因。

3.2 数据清洗:把脏数据洗干净

数据拿到手,第一件事不是分析,是清洗。你想想看,微信接口返回的性别字段,值可能是 1、2、0,也可能是「男」「女」「未知」。年龄字段更离谱,有人填 1900 年出生,有人填 2025 年。地域字段里,「北京」和「北京市」并存,「广东」和「广东省」混着来。

我一般按以下步骤处理:

3.2.1 性别字段标准化

微信接口返回的性别值:1 代表男性,2 代表女性,0 代表未知。但很多业务系统存的是中文。我的做法是统一转成数字编码:

def clean_gender(gender_raw):
    """
    性别清洗函数
    输入:原始性别值(int 或 str)
    输出:标准化后的性别编码(1=男,2=女,0=未知)
    """
    if isinstance(gender_raw, int):
        # 微信接口标准值
        if gender_raw in [1, 2]:
            return gender_raw
        else:
            return 0
    elif isinstance(gender_raw, str):
        gender_map = {
            '男': 1, '男性': 1, '先生': 1, 'M': 1, 'male': 1,
            '女': 2, '女性': 2, '女士': 2, 'F': 2, 'female': 2,
            '未知': 0, '保密': 0, '': 0
        }
        return gender_map.get(gender_raw.strip(), 0)
    else:
        return 0
注意: 性别字段的缺失率通常很高。我见过一个项目,性别「未知」占比超过 60%。这时候别急着分析,先想想为什么——是不是授权流程没引导用户填写?还是接口权限没开全?

3.2.2 年龄字段处理

年龄数据的问题最多。微信接口不直接返回年龄,只返回「年龄范围」,比如「18-24岁」「25-29岁」。但有些第三方 SDK 会返回出生年份,这时候就需要自己算年龄。

我遇到过最离谱的情况:用户出生年份填了 1800 年,年龄算出来 200 多岁。还有填 2026 年的,还没出生呢。所以必须做范围校验:

def clean_age(birth_year, current_year=2025):
    """
    年龄清洗函数
    输入:出生年份(int),当前年份(int)
    输出:清洗后的年龄(int),异常值返回 -1
    """
    if not isinstance(birth_year, int):
        return -1
    
    # 合理的出生年份范围:1900 ~ 当前年份
    if birth_year < 1900 or birth_year > current_year:
        return -1
    
    age = current_year - birth_year
    
    # 合理的年龄范围:0 ~ 120
    if age < 0 or age > 120:
        return -1
    
    return age

核心原则: 对于年龄数据,宁可标记为「未知」,也不要强行填充一个错误值。我曾经为了凑样本量,把缺失年龄的用户统一填成 30 岁,结果做出来的用户画像完全失真,投放转化率掉了 20%。

3.2.3 地域字段标准化

地域数据是最乱的。微信接口返回的是「国家-省份-城市」三级结构,但不同版本接口的字段名不一样。有的叫 city,有的叫 province,有的直接返回「中国,北京,朝阳区」这种拼接字符串。

我的处理思路是:先拆解,再映射到统一编码体系(比如行政区域代码)。

def clean_region(province_raw, city_raw):
    """
    地域清洗函数
    输入:省份原始值(str),城市原始值(str)
    输出:标准化后的省份、城市名称
    """
    # 省份简称映射
    province_map = {
        '北京': '北京市', '上海': '上海市', '天津': '天津市',
        '广东': '广东省', '广西': '广西壮族自治区',
        '内蒙': '内蒙古自治区', '新疆': '新疆维吾尔自治区',
        # ... 完整映射表略
    }
    
    province_clean = province_map.get(province_raw.strip(), province_raw.strip())
    city_clean = city_raw.strip().replace('市', '')  # 去掉「市」字
    
    return province_clean, city_clean
避坑指南: 我曾经遇到过一个情况——用户的地域字段显示「海外」,但仔细一看,IP 地址是国内的。后来发现是用户开了 VPN。所以地域数据最好结合 IP 归属地做交叉验证,别完全信接口返回的值。

3.3 常见数据质量问题及处理方案

做微信生态数据分析这几年,我总结了几类高频问题,列个表方便大家对照:

问题类型 具体表现 原因分析 处理方案
性别缺失率高 「未知」占比 > 50% 用户未授权、接口权限不足 检查 scope 参数是否包含 user_info;引导用户补充资料
年龄分布异常 大量用户集中在「0-18岁」或「60岁以上」 用户随意填写、默认值未处理 设置合理范围过滤;结合行为数据做交叉验证
地域数据混乱 「北京」和「北京市」并存;「广东」和「广东省」混用 不同接口返回格式不一致 建立统一的地域映射表;清洗时做标准化处理
数据更新滞后 用户搬家了,但地域还是老地址 微信接口数据不是实时更新的 设置数据有效期(如 30 天),过期后重新获取
跨平台数据不一致 公众号和小程序里的用户性别不同 用户在不同平台填写的信息不同 以最新授权数据为准;或取多平台交集

3.4 实战建议:数据质量评估先行

别一上来就做分析。我建议先跑一个数据质量报告,看看每个字段的缺失率、异常值比例、分布情况。具体怎么做?

def data_quality_report(df):
    """
    数据质量评估报告
    输入:DataFrame
    输出:各字段的质量指标
    """
    report = {}
    for col in ['gender', 'age', 'province', 'city']:
        if col not in df.columns:
            continue
        
        total = len(df)
        missing = df[col].isnull().sum()
        unknown = (df[col] == 0).sum() if col == 'gender' else 0
        abnormal = 0
        
        if col == 'age':
            abnormal = ((df[col] < 0) | (df[col] > 120)).sum()
        
        report[col] = {
            '缺失率': f'{missing/total*100:.1f}%',
            '异常率': f'{abnormal/total*100:.1f}%',
            '有效样本': total - missing - abnormal
        }
    
    return report

一句话总结: 用户基础属性的清洗,核心就三件事——标准化、去异常、补缺失。别想着一步到位,数据质量是迭代出来的。我每次接手新项目,第一周基本都在做数据清洗,后面分析才能又快又准。

好了,性别、年龄、地域这块就聊到这儿。下一章咱们聊聊更复杂的用户行为数据——点击、浏览、购买这些,那才是真正考验功力的时候。