# 特征工程 ## 2.1 数据集 ### 2.1.1 可用数据集来源 - **企业内部数据**(如百度业务数据) - **付费接口**(如第三方数据服务) - **公开数据集**(学习阶段推荐): - `sklearn`:内置小规模/大规模数据集(如鸢尾花、新闻文本)。 - `Kaggle`:全球最大的数据科学竞赛平台,含丰富数据集。 - `UCI`:加州大学欧文分校机器学习库,覆盖多领域。 #### 2.1.2 scikit-learn(sklearn)数据集 - **数据集加载方式**: - `sklearn.datasets.load_*()`:获取小规模数据集(如`load_iris()`加载鸢尾花数据集)。 - `sklearn.datasets.fetch_*()`:获取大规模数据集(如`fetch_20newsgroups()`加载新闻文本)。 - **数据集结构**:返回`Bunch`对象(继承自字典),支持`bunch.key`或`dict["key"]`访问属性(如`data`特征、`target`标签、`feature_names`特征名)。 ### 2.1.3 数据集划分 - **训练集(Training Set)**:用于模型训练(占比约70%-80%)。 - **测试集(Test Set)**:用于评估模型泛化能力(占比约20%-30%)。 - **工具函数**:`sklearn.model_selection.train_test_split()` - 输入:特征值`X`、目标值`y`。 - 输出:`X_train, X_test, y_train, y_test`(训练/测试特征与目标)。 ```python from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split def dataset_demo(): """ sklearn 数据集使用 :return: """ # 获取鸢尾花数据集 iris = load_iris() print("鸢尾花数据集的返回值:\n", iris) # 返回值是一个继承自字典的Bench print("鸢尾花的特征值:\n", iris.data) print("鸢尾花的目标值:\n", iris.target) print("鸢尾花特征的名字:\n", iris.feature_names) print("鸢尾花目标值的名字:\n", iris.target_names) print("鸢尾花的描述:\n", iris.DESCR) x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=42) print("训练集的特征值:\n", x_train) print("训练集的目标值:\n", y_train) print("测试集的特征值:\n", x_test) print("测试集的目标值:\n", y_test) print("训练集的数量:\n", x_train.shape) print("测试集的数量:\n", x_test.shape) print("训练集的目标值的数量:\n", y_train.shape) print("测试集的目标值的数量:\n", y_test.shape) return None if __name__ == '__main__': dataset_demo() ``` ## 2.2 特征工程介绍 ### 2.2.1 为什么需要特征工程? 原始数据通常无法直接输入模型,需通过特征工程将其转换为模型可理解的数值形式,直接影响模型性能。 ### 2.2.2 什么是特征工程? 通过**特征提取、预处理、降维**等技术,将原始数据转化为高质量特征的过程。 #### 2.3 特征提取(Feature Extraction) `sklearn.feature_extraction` 将非数值数据(如文本、类别)转换为数值特征的技术。 ##### 2.3.1 字典特征提取(类别→One-Hot编码) - **工具**:`sklearn.feature_extraction.DictVectorizer(sparse=True)` - **原理**:将类别特征转换为二进制向量(One-Hot编码),节省内存(稀疏矩阵存储)。 - **应用场景**: - 数据集中的类别特征较多(如性别、职业)。 - 原始数据本身为字典格式(如`{"性别": "男", "职业": "教师"}`)。 ```python from sklearn.feature_extraction import DictVectorizer def dict_vectorizer_demo(): """ 测试字典向量化 :return: """ data = [{'city': '北京', 'temperature': 100}, {'city': '上海', 'temperature': 60}, {'city': '深圳', 'temperature': 30}] # 1.实例化一个转换器的对象 transformer = DictVectorizer(sparse=True) # 2.调用fit_transform data_new = transformer.fit_transform(data) print("转换后的数据:\n", data_new) print("转换后的数据对应的特征名字:\n", transformer.get_feature_names_out()) if __name__ == '__main__': dict_vectorizer_demo() # 2.测试字典向量化 ``` ##### 2.3.2 文本特征提取 - **CountVectorizer**:统计文本中特征词的出现次数(词袋模型)。 - 支持`stop_words`参数过滤停用词(如“的”“是”等无意义词汇)。 ```python from sklearn.feature_extraction.text import CountVectorizer import jieba def count_chinese_demo(): """ 测试中文文本特征抽取 :return: """ data = ['我 爱 北京 天安门', '天安门 上 太阳 升'] # 1.创建一个转换器对象 transformer = CountVectorizer() # 2.调用fit_transform data_new = transformer.fit_transform(data) print("转换后的数据:\n", data_new.toarray()) print("转换后的数据对应的特征名字:\n", transformer.get_feature_names_out()) return None def cut_words(text): return " ".join(jieba.cut(text)) def count_chinese_demo2(): """ 测试中文文本特征抽取2 :return: """ data = ["今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。", "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。", "如果只用一种方式了解某样事物,你就不会真正了解它,了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"] data_new = [cut_words(text) for text in data] # 1.创建一个转换器对象 transformer = CountVectorizer(stop_words=['一种']) # 2.调用fit_transform data_final = transformer.fit_transform(data_new) print("转换后的数据:\n", data_final.toarray()) print("转换后的数据对应的特征名字:\n", transformer.get_feature_names_out()) return None if __name__ == '__main__': # count_chinese_demo() count_chinese_demo2() ``` - **TfidfVectorizer**:基于TF-IDF(词频-逆文档频率)计算特征重要性。 - **TF(词频)**:`词在文档中出现的次数 / 文档总词数`。 - **IDF(逆文档频率)**:`log(总文档数 / 包含该词的文档数)`。 - **TF-IDF**:`TF × IDF`(衡量词对文档的区分度)。 ```python from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer import jieba def tfdif_demo(): """ 测试TF-IDF :return: """ data = ["今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。", "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。", "如果只用一种方式了解某样事物,你就不会真正了解它,了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"] data_new = [cut_words(text) for text in data] # 1.创建一个转换器对象 transformer = TfidfVectorizer(stop_words=['一种']) # 2.调用fit_transform data_final = transformer.fit_transform(data_new) print("转换后的数据:\n", data_final.toarray()) print("转换后的数据对应的特征名字:\n", transformer.get_feature_names_out()) return None if __name__ == '__main__': tfdif_demo() ``` ## 2.4 特征预处理 ### 2.4.1 什么是特征预处理? 对特征进行标准化/归一化,消除量纲影响,提升模型训练效率与效果。 ### 2.4.2 归一化(Normalization) - **目的**:将特征缩放到`[0,1]`或其他固定区间。 - **公式**:`X_scaled = (X - X_min) / (X_max - X_min)`。 - **注意**:易受异常值(最大值/最小值)影响。 ```python from sklearn.preprocessing import MinMaxScaler import pandas as pd def minmax_demo(): """ 测试归一化 :return: """ # 1.获取数据 data = pd.read_csv("./dating.txt") data_new = data.iloc[:, :3] transformer = MinMaxScaler(feature_range=(0, 1)) data_final = transformer.fit_transform(data_new) print(data_final) return None if __name__ == '__main__': minmax_demo() ``` ### 2.4.3 标准化(Standardization) - **目的**:将特征转换为均值为0、标准差为1的分布。 - **公式**:`X_scaled = (X - μ) / σ`(`μ`为均值,`σ`为标准差)。 - **优势**:抗异常值能力强,适合大数据场景。 ``` from sklearn.preprocessing import StandardScaler import pandas as pd def standard_demo(): """ 测试标准化 :return: """ # 1.获取数据 data = pd.read_csv("./dating.txt") data_new = data.iloc[:, :3] transformer = StandardScaler() data_final = transformer.fit_transform(data_new) print(data_final) return None if __name__ == '__main__': standard_demo() ``` ## 2.5 特征降维 降低特征维度,减少计算成本,同时保留关键信息(避免“维度灾难”)。 ### 2.5.1 特征选择(Filter/Embedded) - **Filter过滤式**:基于统计指标筛选特征(如方差选择法、皮尔逊相关系数)。 - **方差选择法**:删除方差过低的特征(方差小→信息量少)。 - **相关系数**:计算特征间相关性(如`r>0.9`表示高度相关,可保留其一)。 ``` from sklearn.feature_selection import VarianceThreshold from scipy.stats import pearsonr import pandas as pd import matplotlib.pyplot as plt def variance_demo(): """ 过滤低方差特征 :return: """ data = pd.read_csv("./factor_returns.csv") data = data.iloc[:, 1:-2] print("数据集:\n", data) # 1.实例化一个转换器对象 transformer = VarianceThreshold(threshold=5) # 2.调用fit_transform data_new = transformer.fit_transform(data) print("转换后的数据:\n", data_new, data_new.shape) # 3.查看相关系数 r1 = pearsonr(data["pe_ratio"], data["pb_ratio"]) print(r1) r2 = pearsonr(data["revenue"], data["total_expense"]) print(r2) plt.figure(figsize=(20, 8), dpi=80) plt.scatter(data["revenue"], data["total_expense"]) plt.show() return None if __name__ == '__main__': variance_demo() ``` - **Embedded嵌入式**:通过模型训练自动选择特征(如决策树的特征重要性、L1正则化)。 ### 2.5.2 主成分分析(PCA) - **工具**:`sklearn.decomposition.PCA(n_components=None)` - **参数**: - `n_components`:保留的特征数(整数)或保留的信息比例(小数,如0.95表示保留95%方差)。 - **应用示例**:用户对物品类别的喜好细分(通过合并用户-物品交叉表,用PCA降维后分析用户偏好)。 ```python import numpy as np from sklearn.decomposition import PCA def pca_demo(): """ 测试主成分分析 :return: """ data = [[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]] print("原始数据:\n", data, np.array(data).shape) # 1.实例化一个转换器对象 transformer = PCA(n_components=0.95) # 2.调用fit_transform data_new = transformer.fit_transform(data) print("转换后的数据:\n", data_new, data_new.shape) return None if __name__ == '__main__': pca_demo() ``` **注**:特征工程是机器学习的核心环节,需结合业务理解与实验验证,才能提取出对模型最有效的特征。