将浮点型特征转换为整数型(量化)的主要方法

2024年12月27日 作者 unix2go

将浮点型特征转换为整数型(量化)的主要方法如下。

  1. 最简单的线性映射方法:
def linear_quantize(data, bits=8):
    # 计算数据范围
    data_min = data.min()
    data_max = data.max()

    # 计算量化步长
    scale = (data_max - data_min) / (2**bits - 1)

    # 线性映射到整数空间
    quantized = np.round((data - data_min) / scale).astype(np.int8)

    return quantized, scale, data_min

# 使用示例
X_float = df['feature'].values
X_int, scale, min_val = linear_quantize(X_float)
  1. 使用MinMaxScaler进行整数映射:
from sklearn.preprocessing import MinMaxScaler

def minmax_quantize(data, max_int=255):
    scaler = MinMaxScaler(feature_range=(0, max_int))
    scaled = scaler.fit_transform(data.reshape(-1, 1))
    return scaled.astype(np.int16), scaler

# 使用示例
X_int, scaler = minmax_quantize(X_float)
  1. 分箱方法(适合非线性分布):
from sklearn.preprocessing import KBinsDiscretizer

def binning_quantize(data, n_bins=256, strategy='quantile'):
    discretizer = KBinsDiscretizer(n_bins=n_bins, 
                                 encode='ordinal', 
                                 strategy=strategy)
    return discretizer.fit_transform(data.reshape(-1, 1)).astype(np.int16)

# 使用示例
X_int = binning_quantize(X_float)
  1. 对数变换后量化(适合偏态分布):
def log_quantize(data, bits=8):
    # 处理零值和负值
    offset = abs(data.min()) + 1 if data.min() <= 0 else 0
    log_data = np.log(data + offset)

    # 线性量化
    return linear_quantize(log_data, bits)

# 使用示例
X_int, scale, min_val = log_quantize(X_float)
  1. 自定义分段量化(适合特定范围):
def custom_quantize(data, boundaries, labels=None):
    if labels is None:
        labels = list(range(len(boundaries) + 1))

    quantized = np.zeros_like(data, dtype=np.int8)

    for i in range(len(boundaries)):
        mask = data > boundaries[i]
        quantized[mask] = labels[i + 1]

    return quantized

# 使用示例
boundaries = [0, 10, 100, 1000]
X_int = custom_quantize(X_float, boundaries)

实际应用建议:

  1. 特征预处理流程:
def preprocess_features(df):
    processed = {}
    for column in df.columns:
        data = df[column].values

        # 检查数据分布
        skewness = stats.skew(data)

        if abs(skewness) > 1.5:
            # 偏态分布使用对数量化
            processed[column], _, _ = log_quantize(data)
        elif data.max() - data.min() > 1000:
            # 大范围数据使用分箱
            processed[column] = binning_quantize(data)
        else:
            # 其他情况使用线性量化
            processed[column], _, _ = linear_quantize(data)

    return pd.DataFrame(processed)
  1. 处理异常值:
def robust_quantize(data, outlier_threshold=3):
    # 移除异常值影响
    mean = np.mean(data)
    std = np.std(data)
    cleaned = np.clip(data, 
                     mean - outlier_threshold * std,
                     mean + outlier_threshold * std)

    return linear_quantize(cleaned)
  1. 保存量化参数以便推理时使用:
import joblib

def save_quantization_params(params, filename):
    joblib.dump(params, filename)

# 量化参数字典
quantization_params = {
    'scale': scale,
    'min_val': min_val,
    'bits': bits,
    'feature_names': feature_names
}

save_quantization_params(quantization_params, 'quant_params.pkl')

重要注意事项:

  1. 量化前要先归一化/标准化
  2. 选择合适的位数(bits)以平衡精度和范围
  3. 不同特征可能需要不同的量化策略
  4. 保存量化参数用于推理
  5. 验证量化后的效果