数据预处理是数学建模中至关重要的一步,它直接影响模型的性能和可靠性。本文将系统介绍数据预处理的各个方面,并结合实际案例展示如何在数学建模中应用这些技术。
数据预处理(Data Preprocessing)是指在进行实际数据分析或机器学习建模之前,对原始数据进行的一系列处理步骤。目的是为了提高数据质量,使得后续的数据分析或模型训练更加有效。通常包括但不限于以下几个方面:
数据清洗(Data Cleaning):
处理缺失值:通过删除、填充平均值、中位数或其他预测方法来处理缺失数据。
异常值检测:识别并处理异常值,这些值可能是因为数据录入错误或是测量错误造成的。
一致性检查:确保所有数据记录遵循相同的格式和单位。
数据集成(Data Integration):
结合来自不同来源的数据,这可能涉及到解决数据冗余和数据冲突的问题。
数据转换(Data Transformation):
规范化/标准化:将数据转换到相同的尺度上,比如将所有数值特征缩放到0到1之间或转换为标准正态分布。
聚集:汇总数据,例如计算平均值、总和等。
数据离散化:将连续数据转换为分类型数据。
创建派生属性:基于现有数据创建新的特征。
数据约简(Data Reduction):
降低数据维度,比如通过主成分分析(PCA)减少特征数量。
采样:减少数据集的大小,例如通过随机抽样获取数据子集。
数据划分(Data Partitioning):
将数据集划分为训练集、验证集和测试集,用于模型的训练、调优和最终评估。
数据清洗综述
数据清洗研究综述_廖书妍.pdf 结构化数据清洗技术综述_郝爽.pdf
[1]郝爽,李国良,冯建华,等.结构化数据清洗技术综述[J].清华大学学报(自然科学版),2018,58(12):1037-1050.DOI:10.16511/j.cnki.qhdxxb.2018.22.053. [1]廖书妍.数据清洗研究综述[J].电脑知识与技术,2020,16(20):44-47.DOI:10.14004/j.cnki.ckt.2020.2361. 数据清洗的过程可以描述为:给定具有模式R 的数据库实例I以及数据质量需求;数据清洗是指找到数据库实例I′,它可以满足所有的数据质量需求,同时清洗代价最小。
清洗质量的评价指标
常用的评价指标有准确率、召回率和F值。
考虑一个二分类问题,即实例被分为正类和负类,那么:准确率定义为被分类器判断为正类的实例中正确分类的比例;
召回率定义为分类器将正类判断为正类的比例;
而F值是准确率和召回率的调和平均值。
数据噪声的类型与检测
数据缺失
直接检测是否为空
数据冗余
其问题在于,重复元组(行)数据的所有特征并不一定相同,甚至都要相同,但其确实指的是同一个元组。例如:
相同员工数据元组,级别 特征不同,其他特征相同;可以直接对比关键特征(姓名)相同的元组,但此例中如何区分同名者和数据冗余也是个问题。
名称特征分别为iPad 2nd和iPad Two的两个元组,所有特征都不相同。可以先聚类(相当于分类问题,方法有:相似度函数,规则判断,机器学习等),缩小搜索空间。
基于字段的检测算法。可以采用LevenshteinDistance算法、余弦相似度函数算法进行字段的相似度检测,以识别冗余的数据。Levenshtein Distance算法易于实现。余弦相似度算法更多地用于检测文本的相似度。通过该算法获得的相似性度量的值越小,说明个体间越相似。
基于记录的检测算法。有N-Grams算法、聚类算法、SNM算法、MPN算法等。N-Grams算法生成一个哈希表,然后根据哈希表来判断记录之间的相似性;聚类算法通过计算将相似的数据归为一类;SNM算法实现较为容易,但在很大程度上取决于关键字,依赖性较强;MPN算法的优点是它可以更为全面地收集重复的数据,但使用起来较为烦琐。
数据冲突
通过完整性约束可以检测数据冲突,而完整性约束可以从干净的数据集中学得。
不同的完整性约束有不同的学习方法,但许多完整性约束都是基于函数依赖设计的。函数依赖的学习算法分为自上而下和自下而上两类
自上而下:假设所有属性都相互依赖开始,然后逐步地去除那些实际上不存在的依赖关系。TANE、FD_Mine、FUN等
自下而上:从单个属性开始,逐步构建起更大范围的依赖关系等。FastFDs、Dep-Miner等。
数据错误
指数据库实例中某些不为 空的属性值是错误的,例如属性域错误、拼写错 误、格式错误等。数据错误有时会引发数据冲突, 但是不冲突的数据不一定是正确数据。
基于完整性约束的错误检测。完整性约束可以用来检测数据冲突,但是约束本身无法指出冲突的发生是由哪个属性值引发的。
基于规则的错误检测。在关系表和主数据之间建立匹配关系,若关系表中的属性值和与其匹配到的主数据中的属性值不相等,就可以判断关系表中的数据存在错误。
基于统计和机器学习的错误检测。基于统计和机器学习的错误检测算法多是基于统计分析的:通过概率模型或关系依赖模型获得输入数据集的定量统计信息,比如属性值的共现信息, 然后通过真值推理来检查原始数据值是否在期望范 围内,或者查找不符合输入数据整体分布的属性值,这些属性值就是错误的属性值。
面向离群点检测的方法。主要包括基于统计模型的算法、基于接近度的算法、基于密度的算法以及基于聚类的算法等。
数据转换与添加
标准化(Standardization,Z-score 标准化)
这种方法将数据转换成标准正态分布的形式,即均值为0,标准差为1。
计算特征x均值
| 优点 | 使不同特征具有相同的尺度。数据的距离信息得以保留。不太受异常值的影响。 |
|---|---|
| 缺点 | 非正态分布的数据标准化后其分布显著改变。大数据集运算时间长。 |
| 适用场景 | 对特征尺度敏感的算法(SVM,线性回归/逻辑回归),依赖于距离的算法(K均值聚类) |
x
from sklearn.datasets import fetch_california_housingfrom sklearn.preprocessing import StandardScalerimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as sns
# 加载数据集california = fetch_california_housing()data = pd.DataFrame(california.data, columns=california.feature_names)
# 原始数据统计信息print("原始数据统计信息:\n", data.describe())
# 标准化scaler = StandardScaler()data_scaled = scaler.fit_transform(data)
# 将标准化后的数据转为DataFramedata_scaled = pd.DataFrame(data_scaled, columns=california.feature_names)
# 标准化后数据统计信息print("标准化后数据统计信息:\n", data_scaled.describe())
# 可视化前后数据分布plt.figure(figsize=(16, 6))
# 标准化前的分布plt.subplot(1, 2, 1)sns.histplot(data['MedInc'], kde=True, color='blue')plt.title('Distribution of Median Income before Standardization')
# 标准化后的分布plt.subplot(1, 2, 2)sns.histplot(data_scaled['MedInc'], kde=True, color='red')plt.title('Distribution of Median Income after Standardization')
plt.show()归一化(Normalization,Min-Max标准化)
这种方法将每个特征的值重新映射到[0, 1]区间内
| 优点 | 使不同特征具有相同的尺度,数据的整体分布形状得以保留。 |
|---|---|
| 缺点 | 包含明显离群值的数据,标准化可能会受到影响,导致结果不理想。 |
| 适用场景 | 神经网络:神经网络中的权重更新可能受益于数据的规范化;主成分分析:依赖于特征之间的协方差矩阵* |
*当特征的尺度不一致时,即某些特征的取值范围远大于其他特征,这会导致协方差矩阵的某些元素远大于其他元素。在这种情况下,PCA 的结果可能会偏向于那些尺度较大的特征,因为这些特征在协方差矩阵中占据主导地位。例如,如果一个特征的取值范围是 0-1000,而另一个特征的取值范围是 0-1,那么前者对协方差矩阵的贡献将远远超过后者,即使后者在数据中可能同样重要。
xfrom sklearn.datasets import load_irisfrom sklearn.preprocessing import MinMaxScalerimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as sns
# 加载数据集iris = load_iris()data = pd.DataFrame(iris.data, columns=iris.feature_names)
# 原始数据统计信息print("原始数据统计信息:\n", data.describe())
# 归一化scaler = MinMaxScaler()data_normalized = scaler.fit_transform(data)
# 将归一化后的数据转为DataFramedata_normalized = pd.DataFrame(data_normalized, columns=iris.feature_names)
# 归一化数据统计信息print("归一化后数据统计信息:\n", data_normalized.describe())
# 可视化前后数据分布plt.figure(figsize=(16, 6))
# 归一化前的分布plt.subplot(1, 2, 1)sns.histplot(data['sepal length (cm)'], kde=True, color='green')plt.title('Distribution of Sepal Length before Normalization')
# 归一化后的分布plt.subplot(1, 2, 2)sns.histplot(data_normalized['sepal length (cm)'], kde=True, color='orange')plt.title('Distribution of Sepal Length after Normalization')
plt.show()归一化到单位长度(Normalization to Unit Length)
这种方法计算每个向量相对于其自身的长度(或范数),通常使用L2范数。
最大值归一化(Max Normalization)
将所有数据除以最大的绝对值。
时间序列频率转换
[1]张春华,高铁梅,陈飞.经济时间序列频率转换方法的研究与应用[J].统计研究,2017,34(02):92-100.DOI:10.19343/j.cnki.11-1302/c.2017.02.009. 经济时间序列频率转换方法的研究与应用_张春华.pdf 由于所获得指标的数据频率有时可能不同(如年度、季度或月度) ,而计量经济模型又要求变量的样本频率必须相同,因而无法一起使用,需要将其中的某些指标进行频率转换,以达到数据频率的统一,例如衡量经济总量的国内生产总值(GDP)是观测实体经济状况最为全面有效的指标,但是公布的GDP指标只有季度和年度数据,当计量经济模型需要使用月度频率的GDP数据时,就需要进行频率转换。
传统频率转换方法
线性插值:这是一种简单的数值插值方法,通过直线连接两个已知数据点来估算未知数据点的值。
二次插值:类似于线性插值,但使用二次曲线来连接数据点,提供更平滑的插值。
拉格朗日插值:一种多项式插值方法,可以根据已知点构造一个多项式函数来近似中间值。
三次样条函数插值:这种方法使用分段的三次多项式来平滑地连接数据点,提供比线性和二次插值更精确的结果。
前沿频率转换方法
Denton 方法
原理:Denton 方法最初由 Denton 在 1971 年提出,旨在通过数值平滑并使用优化方法来保持低频数据的变化趋势。该方法后来经过多次修正和完善。
特点:Denton 方法是一种全局插值方法,即修改低频数据序列中的任何一个点或增加数据点都会影响到整个高频插值序列。
Chow-Lin 方法
原理:Chow-Lin 方法由 Chow 和 Lin 在 1971 年提出,基于稳态多变量回归分析来插值高频数据。该方法假设高频数据序列中的随机扰动项服从一阶自回归 AR(1) 过程。
特点:通过建立一个包含多个高频数据解释变量的回归模型来估计高频序列,这种方法同样是全局插值方法。
Litterman 方法
原理:Litterman 方法与 Chow-Lin 方法类似,区别在于 Litterman 方法假定方程中的随机扰动项服从随机游走过程。
特点:该方法也是全局插值方法,任何低频数据点的变化都会影响高频插值序列。
混频数据模型(Mixed Data Sampling, MIDAS)
原理:混频数据模型允许直接将不同频率的变量纳入同一个模型中,通过考虑高频数据变量样本数据的特征来估计模型参数。
特点:该方法可以处理指数变量和存量变量,但通常不适合直接处理流量变量。此外,混频数据模型需要采用特定的模型形式,缺乏一定的灵活性。
独热编码(One-Hot Encoding)
为每个类别创建一个二进制特征,每个特征表示一个类别是否存在。
每个类别C_i被表示为一个长度为m的二进制向量,其中第i位为1,其余为0。
可以使用sklearn.preprocessing.OneHotEncoder实现
xxxxxxxxxx#来自https://mp.weixin.qq.com/s/qOe-jdj1jqqko9vLzgS67Qimport pandas as pdfrom sklearn.preprocessing import OneHotEncoderimport matplotlib.pyplot as pltimport seaborn as sns
# 创建示例数据data = pd.DataFrame({ 'Gender': ['Male', 'Female', 'Female', 'Male', 'Female', 'Male', 'Male', 'Female']})
# 独热编码onehot_encoder = OneHotEncoder(sparse=False)gender_encoded = onehot_encoder.fit_transform(data[['Gender']])
# 将独热编码后的数据转为DataFramegender_encoded_df = pd.DataFrame(gender_encoded, columns=onehot_encoder.categories_[0])
# 可视化独热编码结果plt.figure(figsize=(8, 6))sns.heatmap(gender_encoded_df, annot=True, cbar=False, cmap='coolwarm')plt.title('One-Hot Encoded Gender')plt.xlabel('Gender')plt.ylabel('Sample Index')plt.show()
print("独热编码结果:\n", gender_encoded_df)过采样(Over-sampling)
过采样的目标是通过复制少数类样本来平衡类别分布,主要方法包括简单复制和SMOTE(合成少数类过采样技术)。
SMOTE的核心步骤如下
选择样本: 从少数类样本中随机选择一个样本
。在少数类样本中找到一个最近邻样本
。生成新样本: 在原样本和一个最近邻样本之间生成一个新样本 ,其计算公式为:
可以通过imblearn.over_sampling.SMOTE来实现
xxxxxxxxxx#来自https://mp.weixin.qq.com/s/qOe-jdj1jqqko9vLzgS67Qfrom sklearn.datasets import make_classificationfrom imblearn.over_sampling import SMOTEimport matplotlib.pyplot as pltimport seaborn as sns
# 创建不平衡数据集X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_clusters_per_class=1, weights=[0.9, 0.1], random_state=42)
# 使用SMOTE进行过采样smote = SMOTE(random_state=42)X_resampled, y_resampled = smote.fit_resample(X, y)
# 可视化过采样前后的数据分布plt.figure(figsize=(16, 6))
# 过采样前plt.subplot(1, 2, 1)sns.scatterplot(X[:, 0], X[:, 1], hue=y, palette='coolwarm')plt.title('Before SMOTE')
# 过采样后plt.subplot(1, 2, 2)sns.scatterplot(X_resampled[:, 0], X_resampled[:, 1], hue=y_resampled, palette='coolwarm')plt.title('After SMOTE')
plt.show()降采样(Under-sampling)
降采样的目标是通过减少多数类样本来平衡类别分布。最简单的方法是随机采样,即从多数类中随机选择与少数类同等数量的样本。
可以采用imblearn.under_sampling.RandomUnderSampler来实现
xxxxxxxxxx#来自https://mp.weixin.qq.com/s/qOe-jdj1jqqko9vLzgS67Qfrom sklearn.datasets import make_classificationfrom imblearn.under_sampling import RandomUnderSamplerimport matplotlib.pyplot as pltimport seaborn as sns
# 创建不平衡数据集X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_clusters_per_class=1, weights=[0.9, 0.1], random_state=42)
# 使用随机降采样undersampler = RandomUnderSampler(random_state=42)X_resampled, y_resampled = undersampler.fit_resample(X, y)
# 可视化降采样前后的数据分布plt.figure(figsize=(16, 6))
# 降采样前plt.subplot(1, 2, 1)sns.scatterplot(X[:, 0], X[:, 1], hue=y, palette='coolwarm')plt.title('Before Under-sampling')
# 降采样后plt.subplot(1, 2, 2)sns.scatterplot(X_resampled[:, 0], X_resampled[:, 1], hue=y_resampled, palette='coolwarm')plt.title('After Under-sampling')
plt.show()
数据约简
| 约简算法分类 | 思想 |
|---|---|
| 过滤式方法 | 是独立于后续机器学习算法的,它通过一些统计度量来评估特征的重要性,例如卡方检验、互信息、相关系数等。 |
| 包裹式方法 | 依赖于特定的学习算法,通过选择特征子集来训练模型,并根据模型的表现来评估特征的重要性。 |
| Name | 随机森林重要性排序 | Boruta算法 | mRMR算法 | HOML算法 |
|---|---|---|---|---|
| 核心思想 | 利用特征在树中的使用频率或者特征在分割节点上的减少不纯度来衡量特征的重要性。 | 基于随机森林的特征选择方法,通过引入随机化的“阴影特征”来判断现有特征是否优于随机特征。 | 基于最大相关性最小冗余的原则来选择特征,旨在选择那些与目标变量高度相关同时与其他特征低度相关的特征。 | 利用模拟退火来跳出局部最优解,遗传算法来探索全局解空间,以及贪婪算法来加速搜索过程。这种混合方法使得算法能够在复杂问题中寻找到较好的解决方案。 |
| 优点 | 可以有效地处理高维数据,并且可以自动处理缺失值。 | 可以处理特征间复杂的相互作用,并且能区分重要特征和冗余特征。 | 减少特征间的冗余。 | 适用于多标签分类问题,这类问题通常比单标签分类更加复杂,因为一个样本可能属于多个类别。 |
| 缺点 | 可能对噪音数据敏感。 | 计算复杂度较高,尤其是在创建阴影特征样本时。 | 计算时间长,特别是在特征数量较大的时候。 | 可解释性差;需要对算法参数进行适当的调整 |
| 适用范围 | 适用于具有大量特征的数据集。 | 适用于需要严格区分重要特征和冗余特征的场景。 | 适用于特征之间存在冗余的情况。 | 计算复杂度最高 |
##
Boruta算法
[1]陈逸杰,唐加山.改进Boruta算法在特征选择中的应用[J].软件导刊,2019,18(04):69-73.
改进Boruta算法在特征选择中的应用_陈逸杰.pdf Boruta算法是一种用于特征选择的包装方法,它主要围绕随机森林分类器构建。这个算法的特点在于它引入了“阴影特征”(Shadow Features)的概念,这些阴影特征是通过打乱原始特征的值来创建的,目的是为了评估每个特征相对于随机噪声的重要性。
Boruta算法的基本步骤包括:
复制样本:将原始数据集复制一份。
创建阴影特征:对复制的数据集中的每列数据进行随机排列,从而创建阴影特征。
合并样本:将原始特征与阴影特征合并,形成一个新的数据集。
运行随机森林分类器:在这个新的数据集上运行随机森林算法,并计算每个特征的重要性。
特征标记:如果某个特征的重要性低于阴影特征的平均重要性,则该特征被标记为“不重要”;如果特征的重要性高于最好的阴影特征的重要性,则被标记为“重要”。
重复过程:删除阴影特征,并重复上述过程,直到所有特征都被标记为“重要”或“不重要”。
使用 URL 乳腺癌威斯康星(诊断)数据集 进行传统Bourta复现
Boruta算法对于URL 乳腺癌威斯康星(诊断)数据集的应用.txt
xxxxxxxxxximport pandas as pdfrom sklearn.model_selection import train_test_splitfrom boruta import BorutaPyfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.metrics import accuracy_scoreimport matplotlib.pyplot as pltimport seaborn as snsimport numpy as np# # 加载数据 红酒# url = "http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data"# columns = ['Class', 'Alcohol', 'Malic acid', 'Ash', 'Alcalinity of ash', 'Magnesium', 'Total phenols',# 'Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins', 'Color intensity', 'Hue',# 'OD280/OD315 of diluted wines', 'Proline']# wine_data = pd.read_csv(url, header=None, names=columns) # X = wine_data.drop('Class', axis=1)# y = wine_data['Class']
# 准备数据 乳腺癌威斯康星(诊断)数据集# 第一列为 ID(标识符)。# 第二列为 Diagnosis(诊断结果,M表示恶性,B表示良性)。# 其余列是特征数据。# 数据集URLurl = "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data"
# 定义列名column_names = ['ID', 'Diagnosis'] + [f'Feature_{i}' for i in range(1, 31)]
# 读取数据cancer_data = pd.read_csv(url, header=None, names=column_names)
# 删除ID列cancer_data.drop('ID', axis=1, inplace=True)
# 将诊断结果转换为数字cancer_data['Diagnosis'] = cancer_data['Diagnosis'].map({'M': 1, 'B': 0})
# 准备数据X = cancer_data.drop('Diagnosis', axis=1)y = cancer_data['Diagnosis']
# 划分训练集和测试集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# 初始化随机森林模型rf = RandomForestClassifier(n_jobs=-1, class_weight='balanced', max_depth=5)
# 初始化Boruta特征选择器boruta_selector = BorutaPy(rf, n_estimators='auto', verbose=2, random_state=42)
# 对训练数据进行特征选择boruta_selector.fit(X_train.values, y_train.values)
# 检查选中的特征selected_features = X_train.columns[boruta_selector.support_].tolist()print("Selected Features: ", selected_features)
# 打印被剔除的特征rejected_features = X_train.columns[~boruta_selector.support_].tolist()print("Rejected Features: ", rejected_features)
# 打印有待定性的特征tentative_features = X_train.columns[boruta_selector.support_weak_].tolist()print("Tentative Features: ", tentative_features)
# 获取特征排名feature_ranks = boruta_selector.ranking_
# 将特征名称和排名结合成一个DataFramefeature_importance_df = pd.DataFrame({ 'Feature': X_train.columns, 'Rank': feature_ranks})print(feature_importance_df)
# 初始化存储特征排名的 DataFrameranking_df = pd.DataFrame(index=range(1, 21), columns=X_train.columns)
# 运行 Boruta 20 次for i in range(20): print(f"Iteration {i+1}") # 初始化Boruta特征选择器 boruta_selector = BorutaPy(rf, n_estimators='auto', verbose=2, random_state=i, max_iter=50) # 对训练数据进行特征选择 boruta_selector.fit(X_train.values, y_train.values) # 获取特征排名 feature_ranks = boruta_selector.ranking_ # 将特征排名保存到 DataFrame 中 ranking_df.loc[i+1] = feature_ranks
# 确保数据集中只有数值列numeric_ranking_df = ranking_df.apply(pd.to_numeric, errors='coerce')
# 计算每个特征的中位数median_values = numeric_ranking_df.median()
# 根据中位数对列进行排序sorted_columns = median_values.sort_values().index
# 设置绘图风格plt.figure(figsize=(15, 8))sns.set(style="whitegrid")
# 绘制箱线图sns.boxplot(data=numeric_ranking_df[sorted_columns], palette="Greens")plt.xticks(rotation=90)plt.title("Sorted Feature Ranking Distribution by Boruta", fontsize=16)plt.xlabel("Attributes", fontsize=14)plt.ylabel("Importance", fontsize=14)plt.tight_layout()plt.show()mRMR算法
[1]李扬,顾雪平.基于改进最大相关最小冗余判据的暂态稳定评估特征选择[J].中国电机工程学报,2013,33(34):179-186+27.DOI:1 0.13334/j.0258-8013.pcsee.2013.34.024. 基于改进最大相关最小冗余判据的暂态稳定评估特征选择_李扬.pdf 其核心思想是从给 定的特征集合中寻找与目标类别有最大相关性且 相互之间具有最少冗余性的特征子集。
给定两个随机变量x和y,其概率密度为p(x) 和p(y),联合概率密度为p(x,y),则x和y之间的互信息定义为
使用 URL 乳腺癌威斯康星(诊断)数据集 进行传统mRMR复现
mrmr库的按照需要采用如下命令
xxxxxxxxxxpip install mrmr_selectionxxxxxxxxxximport pandas as pdfrom mrmr import mrmr_classifimport matplotlib.pyplot as pltimport seaborn as snsimport numpy as np
# 数据集URLurl = "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data"
# 定义列名column_names = ['ID', 'Diagnosis'] + [f'Feature_{i}' for i in range(1, 31)]
# 读取数据cancer_data = pd.read_csv(url, header=None, names=column_names)
# 删除ID列cancer_data.drop('ID', axis=1, inplace=True)
# 将诊断结果转换为数字cancer_data['Diagnosis'] = cancer_data['Diagnosis'].map({'M': 1, 'B': 0})
# 准备数据X = cancer_data.drop('Diagnosis', axis=1)y = cancer_data['Diagnosis']
# 可视化相关性矩阵correlation_matrix = X.corr()plt.figure(figsize=(12, 10))sns.heatmap(correlation_matrix, annot=True, fmt=".2f", cmap='coolwarm')plt.title("Correlation Matrix of Features")plt.show()
# 应用mrmr库进行RMR算法选择特征#selected_features = mrmr_classif(X=X, y=y, K=10) # 选择前10个特征
#print("Selected features:", selected_features)
# 计算每个特征与目标变量的相关性correlation_with_target = X.corrwith(y).sort_values(ascending=False)
# 计算互信息def estimate_joint_probability(data): """估计联合概率分布""" values, counts = np.unique(data, return_counts=True) joint_prob = counts / float(data.size) return values, joint_prob
def marginal_probability(data): """计算边缘概率分布""" values, counts = np.unique(data, return_counts=True) marginal_prob = counts / float(data.size) return marginal_prob
def mutual_information(x, y, bins=10): """计算两个变量之间的互信息""" c_xy, _, _ = np.histogram2d(x, y, bins=bins) c_xy = c_xy / np.sum(c_xy) px = marginal_probability(x) py = marginal_probability(y) mi = 0 for i in range(bins): for j in range(bins): if c_xy[i, j] > 0: mi += c_xy[i, j] * np.log2(c_xy[i, j] / (px[i] * py[j])) return mi
# 最大化相关性和最小化冗余selected_features = []num_features_to_select = 10while len(selected_features) < num_features_to_select: max_gain = -np.inf best_feature = None for feature in X.columns: if feature not in selected_features: gain = correlation_with_target[feature] - sum([mutual_information(X[feature], X[f]) for f in selected_features]) if gain > max_gain: max_gain = gain best_feature = feature selected_features.append(best_feature)
# 可视化特征选择过程fig, ax = plt.subplots(figsize=(10, 6))ax.barh(range(len(selected_features)), [correlation_with_target[f] for f in selected_features], color='skyblue')ax.set_yticks(range(len(selected_features)))ax.set_yticklabels(selected_features)ax.set_xlabel('Correlation with Target')ax.set_title('Selected Features by mRMR')plt.show()
# 可视化特征之间的相关性selected_X = X[selected_features]correlation_matrix_selected = selected_X.corr()plt.figure(figsize=(10, 8))sns.heatmap(correlation_matrix_selected, annot=True, fmt=".2f", cmap='coolwarm')plt.title("Correlation Matrix of Selected Features")plt.show()补充
完整性约束
在数据库管理和数据清理的过程中,“完整性约束”(Integrity Constraints)指的是用来保证数据库中数据准确性和一致性的规则集合。这些约束条件确保了数据符合预期的结构和逻辑关系,从而防止错误或不一致的数据进入数据库系统。以下是几种常见的完整性约束:
实体完整性(Entity Integrity):
每个表必须有一个主键(Primary Key),该主键唯一标识表中的每一条记录,并且不允许为空(NULL)。
参照完整性(Referential Integrity):
这是关于外键(Foreign Key)的规则,当一个表引用另一个表的主键时,被引用的主键必须存在于目标表中。如果删除了一个主键记录,则需要更新或删除所有依赖于该主键的外键记录,以保持数据一致性。
域完整性(Domain Integrity):
定义了字段的有效输入范围或类型。例如,年龄字段只能包含非负整数,或者电子邮件地址字段必须符合电子邮件地址的标准格式。
用户定义的完整性(User-defined Integrity):
用户可以根据业务需求定义额外的约束,如检查约束(CHECK约束),它可以是一个布尔表达式,用于限制列中的值或多个列之间的关系。
数据一致性(Data Consistency):
维护数据的一致性意味着确保事务在执行前后数据保持一致状态。例如,转账操作应该确保从一个账户转出的金额等于另一个账户转入的金额。
在数据清洗过程中,完整性约束可以帮助识别和纠正数据中的错误,例如无效值、重复记录、违反参照完整性的记录等。通过应用这些约束,可以确保数据库中的数据始终保持准确、可靠和可用的状态。这对于任何依赖于高质量数据的应用程序都是至关重要的。
滑动窗口(Sliding Window)
滑动窗口(Sliding Window)是一种处理时间序列数据和其他序列数据的技术,常用于生成固定长度的输入序列,用于训练模型。这种方法特别适用于时间序列预测、图像处理等序列数据处理领域。
滑动窗口的具体步骤可以概括为以下几个步骤:
定义窗口大小:
确定窗口的长度(窗口大小),即每个片段包含多少个数据点。这个长度可以根据问题的具体需求来选择。
定义步长:
确定窗口移动的步长(步幅),即每次移动多少个数据点。步长可以等于窗口大小(即不重叠),也可以小于窗口大小(即有重叠)。
生成窗口序列:
从原始时间序列数据中,按照定义的窗口大小和步长,生成一系列的窗口序列。
构造输入输出对:
对于每个窗口序列,将其作为模型的输入(特征),并根据业务需求定义对应的输出(目标)。例如,预测下一个时间点的值时,可以将窗口序列作为输入,将下一个时间点的值作为输出。
xxxxxxxxxximport numpy as np
def sliding_window(data, window_size, step_size=1): """ 生成滑动窗口序列。 :param data: 输入的时间序列数据 :param window_size: 窗口大小 :param step_size: 步长,默认为1 :return: 生成的窗口序列 """ # 确保数据是numpy数组 data = np.array(data) # 计算可以生成的窗口数量 num_windows = ((len(data) - window_size) // step_size) + 1 # 初始化输出数组 windows = np.zeros((num_windows, window_size)) # 生成窗口序列 for i in range(num_windows): start = i * step_size end = start + window_size windows[i] = data[start:end] return windows
# 示例数据data = np.random.rand(10) # 生成一个长度为10的随机序列window_size = 3 # 窗口大小为3step_size = 1 # 步长为1
# 生成滑动窗口序列windows = sliding_window(data, window_size, step_size)
print("Original data:", data)print("Generated windows:")for window in windows: print(window)参考内容 Python实现数据预处理:常见缺失值处理方法解析 https://mp.weixin.qq.com/s/qNpeQ9hoPGVyjmxxs3bYEQ 特征选择:基于随机森林的Boruta算法应用 https://mp.weixin.qq.com/s/wX1B_2wxp3kUVjQKQE5XLw 通透!十大数据预处理方法 最强总结! https://mp.weixin.qq.com/s/qNpeQ9hoPGVyjmxxs3bYEQ
数据处理实例 Doping:使用精心设计的合成数据测试和评估异常检测器的技术 https://mp.weixin.qq.com/s/-Fd2xqacThNyhYuPw5fv4g 基于距离度量学习的异常检测:一种通过相关距离度量的异常检测方法 https://mp.weixin.qq.com/s/JfJo-UQjU1vz9ct5YEw37Q 多变量异常检测:工业数据分析中的异常检测技术 https://mp.weixin.qq.com/s/3HdLeusKtFA-2gPyZ4sG-A
One thought on “【数学建模】001 数据预处理”
Comments are closed.