哈尔滨市网站建设_网站建设公司_网站备案_seo优化
2026/1/12 23:14:07 网站建设 项目流程

数据降维与特征工程:两步让你的模型从“勉强能用”到“脱颖而出”

引言:你是不是也遇到了这些模型优化的痛点?

作为一名刚入门机器学习的开发者,你可能有过这样的经历:

  • 拿到原始数据直接喂给模型,结果准确率卡在70%上不去,无论换什么模型(逻辑回归→随机森林→XGBoost)都没用;
  • 特征列表拉得老长(比如用户行为数据有100+个特征),训练时电脑风扇狂转,跑一个模型要半小时,还容易过拟合;
  • 明明做了特征处理,但模型还是“不识好歹”——比如把“性别”字符串直接丢进去,结果报错说“无法处理非数值特征”。

其实,90%的模型性能问题,根源不在模型本身,而在“数据预处理”。而数据预处理的核心,就是「特征工程」和「数据降维」这两把“剑”:

  • 特征工程是“做加法”:把原始数据转化为更贴合模型逻辑的有效特征(比如把“性别”变成0/1,把“时间”拆成年月日);
  • 数据降维是“做减法”:在保留核心信息的前提下,去掉冗余/无关特征(比如把“身高+体重”合并成“体型”特征)。

本文将用通俗易懂的语言+可复现的实战案例,带你搞懂这两个工具的底层逻辑,以及如何用它们“双剑合璧”提升模型性能。读完本文,你将能:

  1. 从0到1完成「原始数据→有效特征」的处理流程;
  2. 用3种方法快速精简特征,解决“维度灾难”;
  3. 结合两者优化模型,让准确率/训练效率显著提升。

准备工作:你需要这些基础

在开始之前,确认你具备以下条件:

1. 技术知识储备

  • 熟悉Python基础语法(变量、函数、 pandas 操作);
  • 了解机器学习基本概念(特征、标签、训练集/测试集划分);
  • 用过 scikit-learn 库(比如跑过LogisticRegressionRandomForestClassifier)。

2. 环境与工具

  • Python 3.8+(推荐3.10,兼容性最好);
  • 安装必要库:
    pipinstallnumpy pandas scikit-learn matplotlib seaborn featuretools
  • 数据集:本文用泰坦尼克号生存预测数据集(经典入门案例,数据包含乘客信息和生存标签),可从Kaggle下载:Titanic - Machine Learning from Disaster。

第一章:先搞懂“双剑”的本质——特征工程是“质”,降维是“量”

在实战前,我们需要先明确两个核心概念的区别:

1. 特征工程:把“原始数据”变成“模型能听懂的话”

假设你要预测“一个人会不会买某款手机”,原始数据可能有“性别(男/女)”“年龄(25)”“月收入(10000)”“浏览时长(30分钟)”。但模型是“数字驱动”的,它看不懂“男”“女”,也不会自动把“浏览时长30分钟”和“购买意愿”关联起来——这时候就需要特征工程

  • 把“性别”转换成0(男)/1(女)(标签编码);
  • 把“年龄”分成“18-25”“26-35”“36+”(离散化);
  • 计算“月收入/手机价格”的比值(构造新特征)。

简单来说,特征工程是“翻译”——把人类能理解的信息,翻译成模型能理解的数值特征

2. 数据降维:把“冗余信息”删掉,留下“核心矛盾”

假设你有100个特征,但其中50个都是“身高”“体重”“BMI”这类高度相关的特征(比如身高越高,体重往往越大)。这时候模型会被“冗余信息”干扰:

  • 训练时间变长(要处理更多特征);
  • 过拟合风险增加(模型学了很多没用的细节);
  • 结果解释性变差(不知道哪个特征真正起作用)。

数据降维就是“瘦身”——在不丢失关键信息的前提下,减少特征数量。比如用PCA把100个特征压缩到10个,同时保留95%的原始信息。

3. 两者的关系:先“质”后“量”,协同增效

正确的流程应该是:先做特征工程提升特征质量,再用降维减少特征数量。比如:

  • 先把“性别”编码成0/1(特征工程),再用PCA合并“身高+体重”(降维);
  • 如果反过来,先降维再做特征工程,可能会丢失编码后的关键信息。

第二章:特征工程实战——从原始数据到有效特征

我们用泰坦尼克号数据集演示完整的特征工程流程。首先加载数据:

importpandasaspd# 加载数据df=pd.read_csv("titanic.csv")print("原始数据形状:",df.shape)# (891, 12),891条数据,12个特征print("前5行数据:")print(df.head())

原始特征包括:PassengerId(乘客ID)、Survived(生存标签,0=死亡,1=生存)、Pclass(舱位等级)、Name(姓名)、Sex(性别)、Age(年龄)、SibSp(兄弟姐妹/配偶数量)、Parch(父母/子女数量)、Ticket(船票编号)、Fare(船票价格)、Cabin( cabin号)、Embarked(登船港口)。

步骤1:过滤无用特征——先丢“肯定没用”的

首先,我们可以直接丢弃完全不相关重复的特征:

  • PassengerId:只是编号,和生存无关;
  • Name:姓名中的“Mr”“Mrs”可能有用,但姓名本身没用;
  • Ticket:船票编号是随机的,无意义;
  • Cabin:缺失值太多(891条中只有204条有值),暂时丢弃。
# 丢弃无用特征df=df.drop(["PassengerId","Name","Ticket","Cabin"],axis=1)print("过滤后的数据形状:",df.shape)# (891, 8)

步骤2:处理缺失值——模型不喜欢“空值”

缺失值是特征工程的“必做题”,不同类型的特征有不同的处理方式:

(1)数值型特征(Age、Fare)

数值型特征的缺失值可以用均值/中位数/众数填充(优先用中位数,因为不受 outliers 影响)。

fromsklearn.imputeimportSimpleImputer# 处理Age的缺失值(中位数填充)age_imputer=SimpleImputer(strategy="median")df["Age"]=age_imputer.fit_transform(df[["Age"]])# 处理Fare的缺失值(均值填充,因为Fare没有极端值)fare_imputer=SimpleImputer(strategy="mean")df["Fare"]=fare_imputer.fit_transform(df[["Fare"]])
(2)类别型特征(Embarked)

类别型特征的缺失值用众数填充(最常见的类别)。

# 处理Embarked的缺失值(众数填充)embarked_imputer=SimpleImputer(strategy="most_frequent")df["Embarked"]=embarked_imputer.fit_transform(df[["Embarked"]]).ravel()# ravel()转成一维数组

步骤3:编码类别型特征——把“文字”变成“数字”

模型只能处理数值,所以需要把类别型特征(Sex、Embarked、Pclass)转换成数值:

(1)二元类别(Sex:男/女)

标签编码(Label Encoding):把“男”→0,“女”→1。

fromsklearn.preprocessingimportLabelEncoder sex_encoder=LabelEncoder()df["Sex"]=sex_encoder.fit_transform(df["Sex"])# 男→0,女→1
(2)多类别(Embarked:S/C/Q)

独热编码(One-Hot Encoding):把每个类别变成一个新特征(比如Embarked_S→1表示从S港登船,否则0)。

fromsklearn.preprocessingimportOneHotEncoderfromsklearn.composeimportColumnTransformer# 定义要编码的列和编码器categorical_features=[

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询