You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无预定义列类型时,如何识别数字编码的nominal变量?求Python/SAS方案

识别编码为数字的名义变量方法

Python 实现方案

1. 业务规则+关键词匹配法

针对常见的等级类名义变量(如满意度、评级),结合变量名关键词、取值范围和预定义编码映射识别:

  • 提取变量名中的等级相关关键词(如rating、level、grade、status、rank)
  • 检查变量的唯一取值是否为小范围离散整数(如1-3、1-5)
  • 匹配预定义的等级编码映射(如{1: 'Bad', 2: 'Good', 3: 'Better'})

代码示例:

import pandas as pd
import re

def is_nominal_encoded(df, col):
    # 检查变量名是否含等级关键词
    keyword_pattern = re.compile(r'rating|level|grade|status|rank', re.IGNORECASE)
    if keyword_pattern.search(col):
        unique_vals = df[col].unique()
        # 检查取值是否为小范围离散整数
        if all(isinstance(v, int) for v in unique_vals) and len(unique_vals) <= 5:
            return True
    # 匹配预定义等级映射(可根据业务扩展)
    grade_maps = [{1:'Bad',2:'Good',3:'Better'}, {1:'Low',2:'Medium',3:'High'}]
    col_vals = set(df[col].unique())
    for mapping in grade_maps:
        if col_vals == set(mapping.keys()):
            return True
    return False

# 测试用例
data = pd.DataFrame({
    'satisfaction_rating': [1,2,3,2,1,3],
    'age': [25,30,35,40,45,50],
    'product_level': [1,2,1,3,2,3]
})

for col in data.columns:
    print(f"列 {col} 是否为编码的名义变量: {is_nominal_encoded(data, col)}")

2. 统计特征+互信息分析法

名义变量编码后数值间隔无实际意义,可通过统计特征区分:

  • 计算变量与临时分类变量的互信息(互信息越高,越可能是名义变量)
  • 对比熵值:名义变量熵值更接近分类变量,区间变量熵值随取值范围增大而升高

代码示例:

from sklearn.feature_selection import mutual_info_classif
import numpy as np

def check_nominal_via_stats(df, target_col):
    # 将已知区间变量分箱转为临时分类变量作为参考
    temp_cat = pd.cut(df['age'], bins=3, labels=['young','mid','old'])
    # 计算目标变量与临时分类变量的互信息
    mi = mutual_info_classif(df[[target_col]], temp_cat, discrete_features=True)[0]
    # 计算目标变量的熵
    value_counts = df[target_col].value_counts(normalize=True)
    entropy = -np.sum(value_counts * np.log2(value_counts))
    # 阈值可根据业务调整:互信息高+熵值适中(小基数)
    return mi > 0.1 and entropy < 2.0

# 测试用例
print(f"satisfaction_rating 统计特征判断: {check_nominal_via_stats(data, 'satisfaction_rating')}")
print(f"age 统计特征判断: {check_nominal_via_stats(data, 'age')}")

3. 多维度规则引擎判断

综合基数、取值类型、业务关键词避免单一阈值问题:

  • 基数≤10(可根据业务调整,远小于区间变量基数)
  • 取值为非连续整数(无小数、无大跨度连续递增值)
  • 变量名不含amount、price、age等区间变量关键词

SAS 思路

1. PROC FREQ + 变量名规则检查

通过PROC FREQ查看频率分布,结合变量名关键词过滤:

/* 获取数据集内的数值型变量 */
proc sql;
    create table num_vars as
    select name from dictionary.columns
    where libname='WORK' and memname='DATA' and type='num';
quit;

%macro check_nominal;
    %do i=1 %to &sqlobs;
        %let var=%scan(&name_list, &i);
        proc freq data=data;
            tables &var / nocum nocol;
            title "Frequency of &var";
        run;
        /* 检查变量名是否含等级关键词 */
        %if %sysfunc(indexw(%lowcase(&var), rating)) or %sysfunc(indexw(%lowcase(&var), level)) %then %do;
            %put &var is likely an encoded nominal variable;
        %end;
    %end;
%mend;

proc sql noprint;
    select name into :name_list separated by ' ' from num_vars;
quit;

%check_nominal;

2. DATA步逻辑判断

在DATA步中结合唯一值数量、取值范围编写判断逻辑:

data nominal_check;
    set data end=eof;
    array nums _numeric_;
    if _n_=1 then do;
        declare hash h();
        h.defineKey('val');
        h.defineDone();
    end;
    do over nums;
        val = nums;
        h.add();
    end;
    if eof then do;
        do over nums;
            var_name = vname(nums);
            unique_count = h.num_items;
            /* 判断规则:唯一值≤5且为整数 */
            if unique_count <=5 and val=int(val) then do;
                is_nominal = 1;
            end;
            else is_nominal = 0;
            output;
        end;
    end;
    keep var_name is_nominal;
run;

内容的提问来源于stack exchange,提问作者newtostack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 04:24:23