分类标准化

Java 数据清洗

Dennis Lee

Software Engineer

为何要标准化类别?

  • 类别名称不一致:无法分组
  • "Fruits & Vegetables"的不同写法
  • 解决方案:标准化类别

 

 

原始类别 数量
Fruits & Vegetables 10
fruits & veg 20
Fruits&Veg 30
Java 数据清洗

标准化步骤

  1. 定义标准类别
    FRUITS_AND_VEGETABLES
    DAIRY
    UNCATEGORIZED
    
  2. 将变体映射到标准类别
    Fruits & Vegetables -> FRUITS_AND_VEGETABLES
    fruits & veg -> FRUITS_AND_VEGETABLES
    Fruits&Veg -> FRUITS_AND_VEGETABLES
    
  3. 进行分析——例如统计 FRUITS_AND_VEGETABLES 等类别
Java 数据清洗

用 enum 定义标准类别

// Define standard categories
public enum ProductCategory {
    FRUITS_AND_VEGETABLES,
    DAIRY,
    UNCATEGORIZED;
}

// Example category
System.out.println(ProductCategory.FRUITS_AND_VEGETABLES);
FRUITS_AND_VEGETABLES
Java 数据清洗

将原始类别映射到标准类别

import java.util.HashMap;
import java.util.Map;
// Define map of raw category variations to standard categories
Map<String, ProductCategory> rawCategories = new HashMap<>();
// Variation 1: Fruits & Vegetables
rawCategories.put("Fruits & Vegetables", ProductCategory.FRUITS_AND_VEGETABLES);
// Variation 2: fruits & veg
rawCategories.put("fruits & veg", ProductCategory.FRUITS_AND_VEGETABLES);
// Variation 3: Fruits&Veg
rawCategories.put("Fruits&Veg", ProductCategory.FRUITS_AND_VEGETABLES);
Java 数据清洗

映射变体到标准类别:输出

System.out.println(rawCategories.get("fruits & veg")); // Get standard category
FRUITS_AND_VEGETABLES

 

rawCategories:仅用于可视化;列表示 Map 的键值对

原始类别 标准类别
Fruits & Vegetables FRUITS_AND_VEGETABLES
fruits & veg FRUITS_AND_VEGETABLES
Fruits&Veg FRUITS_AND_VEGETABLES
Java 数据清洗

处理未知类别

String unknownCategory = "Mystery Category";

// Return UNCATEGORIZED if category not found in rawCategories
ProductCategory category = rawCategories.getOrDefault(
        unknownCategory, ProductCategory.UNCATEGORIZED);

System.out.println("Unknown: " + category);
Mystery Category: UNCATEGORIZED
原始类别 标准类别
Mystery Category UNCATEGORIZED
Java 数据清洗

使映射不可变

import java.util.Collections;
Map<String, ProductCategory> categories =
        Collections.unmodifiableMap(rawCategories); // Create immutable view

try { categories.put("new", ProductCategory.DAIRY); // Will throw exception } catch (UnsupportedOperationException e) { System.out.println("Cannot modify immutable map"); }
Cannot modify immutable map
Java 数据清洗

从数据集中提取类别

// Extract category and quantity from our grocery inventory dataset
Map<String, Integer> rawData = 
        Map.of("Fruits & Vegetables", 10, 
               "fruits & veg", 20,
               "Fruits&Veg", 30);

rawData:基于杂货库存数据集提取的映射

原始类别 数量
Fruits & Vegetables 10
fruits & veg 20
Fruits&Veg 30
Java 数据清洗

查找标准类别

Map<ProductCategory, Integer> stockByCategory =
        new EnumMap<ProductCategory, Integer>(ProductCategory.class);

rawData.forEach((raw, quantity) -> // Lookup standard category in categories and sum quantities stockByCategory.merge(categories.get(raw), quantity, Integer::sum));

categories:用于查找标准类别的映射

原始类别 标准类别
Fruits & Vegetables FRUITS_AND_VEGETABLES
fruits & veg FRUITS_AND_VEGETABLES
Fruits&Veg FRUITS_AND_VEGETABLES
Java 数据清洗

按标准类别求和

System.out.println(stockByCategory);
{FRUITS_AND_VEGETABLES=60}

 

stockByCategory:在 categoryMap 中查找 rawData 后的映射

标准类别 数量
FRUITS_AND_VEGETABLES 60
Java 数据清洗

按标准类别分组:总结

1) 从数据集中提取类别/数量映射 rawData(如下)

原始类别 数量
Fruits & Vegetables 10

2) 创建 categories 以查找标准类别(如下)

原始类别 标准类别
Fruits & Vegetables FRUITS_AND_VEGETABLES

3) 将 rawDatacategories 中查找后计算 stockByCategory(如下)

标准类别 数量
FRUITS_AND_VEGETABLES 60
Java 数据清洗

整合回顾

关键导入

import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
  • enum 定义标准类别
  • HashMap 构建类别映射
  • Collections.unmodifiableMap 设为不可变
  • .getOrDefault() 处理未知类别
  • .merge() 按标准类别聚合
Java 数据清洗

Passons à la pratique !

Java 数据清洗

Preparing Video For Download...