数据降维与量化处理技术解析
1. 航空公司推文相似度分析
在分析人们对不同航空公司的推文内容时,我们可以使用余弦相似度来衡量它们之间的相似性。以下是计算Delta、United和JetBlue三家航空公司推文向量余弦相似度的代码:
from scipy.spatial.distance import cosine
print(f"Delta | United | {cosine(delta, united):.3f}")
print(f"Delta | JetBlue | {cosine(delta, jetblue):.3f}")
print(f"United | JetBlue | {cosine(united, jetblue):.3f}")
运行结果如下:
| 航空公司对比 | 余弦相似度 |
| — | — |
| Delta | United | 0.239 |
| Delta | JetBlue | 0.930 |
| United | JetBlue | 0.787 |
从结果可以看出,Delta和United在分析中较为相似,而Delta和JetBlue在向量空间中几乎是最远的。余弦相似度值为0表示“情感”向量完全相同,值为1表示差异最大。这让我们可以从抽象的角度思考向量空间。
各航空公司的向量表示如下:
- Delta:
[ 5.578579 2.0885715 -5.8722963 -5.2461944 4.862418 6.6500
3.054988 2.5725224 3.1206055 -9.660177 ]
- United:
[ 0.62689006 2.9862213 -10.10382 -7.578535 -0.443181
3.9621575 2.9998243 -0.11659689 -2.9283297 -7.855896
- JetBlue:
[ 0.04514389 0.03341183 -0.02691341 0.01708637 0.02028313 -0
-0.0415993 -0.04835104 -0.05358113 -0.03369116]
2. 数据分解技术概述
高维数据集可能不太适合建模技术,无论是因为初始数据收集的高维度,还是因为创建了额外的合成特征。在这些情况下,使用较少的特征进行计算可能更易于处理,并且更具预测性。
2.1 主要分解技术
- 主成分分析(PCA) :最常见和最古老的分解技术,由Karl Pearson在1901年首次提出。它通过确定每个原始维度的乘数,线性地推导出主成分。
- 非负矩阵分解(NMF) :适用于特定数据集和值的域特征分布。
- 潜在狄利克雷分配(LDA) :常用于文本主题建模等领域。
- 独立成分分析(ICA) :用于分离数据中的独立成分。
- t - 分布随机邻域嵌入(t - SNE) :一种非线性降维技术,常用于可视化高维数据,但不可逆。
这些分解技术都可以通过scikit - learn库实现。
2.2 旋转与白化
以一个只有两个特征的数据集为例,我们可以进行分解操作。PCA会强调“最重要的合成轴”,并且随着每个连续的PCA特征,方差会减小。白化和球化是对这些合成特征进行重新缩放的同义词。
以下是相关代码示例:
from src.whiten import data, show
# Only two initial features for illustration,
# but in general we would have a high dimensionality
show(data, "Parameter space for two features",
"Raw Feature 1", "Raw Feature 2")
from sklearn.decomposition import PCA
show(PCA().fit_transform(data),
"PCA Components", "Synthetic Axis 1", "Synthetic Axis 2")
在这个例子中,两个特征明显高度相关,并且沿着大约45°的对角线方差比观察轴更大。PCA会重新定向数据,使这个方差轴(即最大熵)成为主要成分。
2.3 降维示例:威斯康星乳腺癌数据集
我们使用威斯康星乳腺癌数据集来展示降维的效果。该数据集包含30个肿瘤的数值测量,目标是将肿瘤特征化为良性或恶性。
以下是具体的操作步骤:
1. 加载数据集并进行标准化处理:
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import StandardScaler
cancer = load_breast_cancer()
X_raw = StandardScaler().fit_transform(cancer.data)
y = cancer.target
- 分别选择1、2和4个主成分进行降维,并使用K近邻模型进行评估:
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
X_pca1 = PCA(n_components=1, whiten=True).fit_transform(X_raw)
X_pca2 = PCA(n_components=2, whiten=True).fit_transform(X_raw)
X_pca4 = PCA(n_components=4, whiten=True).fit_transform(X_raw)
for X in (X_raw, X_pca1, X_pca2, X_pca4):
X_train, X_test, y_train, y_test = (
train_test_split(X, y, random_state=1))
model = KNeighborsClassifier().fit(X_train, y_train)
accuracy = model.score(X_test, y_test)
error_rate = 100*(1-accuracy)
print(f"Features | {X.shape=}\t| {error_rate=:.2f}%")
运行结果如下:
| 特征情况 | 数据形状 | 错误率 |
| — | — | — |
| 原始数据 | (569, 30) | 4.90% |
| 1个主成分 | (569, 1) | 9.79% |
| 2个主成分 | (569, 2) | 6.99% |
| 4个主成分 | (569, 4) | 4.20% |
可以看到,使用4个主成分时,错误率比使用完整原始数据时略低。这表明在数据中的大部分熵被考虑后,剩下的可能只是随机噪声。
2.4 PCA的具体计算
PCA通过确定每个原始维度的乘数来线性推导主成分。以乳腺癌数据集为例,每个观测值是一个30维的向量,每个维度的值乘以一个常数,然后将这些乘积相加得到主成分。
以下是计算示例:
pca3 = PCA(n_components=3).fit(X_raw)
import pandas as pd
pd.DataFrame(pca3.components_.T,
index=cancer.feature_names,
columns=['pca_1', 'pca_2', 'pca_3'])
row0_sk = pca3.transform(X_raw)[0]
row0_np = (pca3.components_ * X_raw[0]).sum(axis=1)
print(f"Row 0 as transform: {row0_sk}")
print(f"Row 0 as mul/sum: {row0_np}")
部分主成分乘数表如下:
| 特征名称 | pca_1 | pca_2 | pca_3 |
| — | — | — | — |
| mean radius | 0.218902 | -0.233857 | -0.00853 |
| mean texture | 0.103725 | -0.059706 | 0.06455 |
| mean perimeter | 0.227537 | -0.215181 | -0.00931 |
|… |… |… |… |
| worst concavity | 0.228768 | 0.097964 | -0.17305 |
| worst concave points | 0.250886 | -0.008257 | -0.17034 |
| worst symmetry | 0.122905 | 0.141883 | -0.27131 |
| worst fractal dimension | 0.131784 | 0.275339 | -0.23279 |
3. 可视化技术
3.1 PCA可视化:手写数字数据集
我们使用手写数字数据集来展示可视化技术。该数据集包含1797个8×8灰度像素的手写数字扫描图像,相当于一个64维的参数空间。
使用PCA将其降维到二维进行可视化的代码如下:
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
digits = load_digits()
pca_digits = PCA(n_components=2).fit_transform(digits.data)
def plot_digits(data, digits, title):
plt.figure(figsize=(10, 10))
plt.scatter(data[:, 0], data[:, 1], c=digits.target, cmap=plt.cm.get_cmap('nipy_spectral', 10))
plt.colorbar()
plt.title(title)
plt.show()
plot_digits(pca_digits, digits, "PCA")
PCA降维后的可视化结果显示,不同数字的区域有一定的区分,但也存在较强的重叠,区分度相对较松散。
3.2 t - SNE可视化
t - SNE是一种非线性降维技术,在可视化方面通常能取得更好的效果。
以下是使用t - SNE进行可视化的代码:
from sklearn.manifold import TSNE
tsne_digits = TSNE(random_state=1).fit_transform(digits.data)
plot_digits(tsne_digits, digits, "t-SNE")
t - SNE的可视化结果显示,数字的聚类效果更强,例如数字0在左中心的聚类非常明显,与其他数字之间有很大的差距。
3.3 UMAP可视化
均匀流形近似与投影(UMAP)是另一种与t - SNE有相似动机但数学原理不同的技术。UMAP通常具有额外的优势,它能大致保留聚类之间的距离。
以下是使用UMAP进行可视化的代码:
from umap import UMAP
umap_digits = UMAP(random_state=1).fit_transform(digits.data)
plot_digits(umap_digits, digits, "UMAP")
UMAP的可视化结果显示,聚类更加紧密,以至于在每个聚类中很难或不可能区分许多重叠的数字。
在使用分解技术生成合成特征时,我们可以根据具体需求,将分解后的维度与原始特征、独热编码特征、多项式特征等结合使用,以构建最适合特定目的的数据集。这通常需要一定的直觉、推理和大量的试验。
4. 量化与二值化
4.1 概念介绍
在某些情况下,连续甚至有序的数据用少量级别表示会更有用。当将数值范围缩减为两个值(如True/False或1/0)时,这种量化称为二值化。量化转换在数据表示的精度超过实际意义时非常有用,无论是从测量精度的角度,还是从数据科学任务的实用性角度来看。
4.2 示例:教程调查数据集
我们使用一个教程调查数据集来展示量化与二值化的应用。该数据集包含了参加教程的学生的一些传记数据以及他们对教程成功程度的1 - 10分评价。
以下是加载数据集并查看部分数据的代码:
import pandas as pd
survey = pd.read_csv('data/ML-survey.csv')
survey.sample(6, random_state=1)
部分数据如下:
| Language | Experience | Age | Post_Secondary | Success |
| — | — | — | — | — |
| C++ | 1.0 | 57 | 12 | 7 |
| Python | 7.0 | 24 | 11 | 5 |
| R | 2.0 | 46 | 9 | 10 |
| Python | 2.0 | 23 | 3 | 5 |
| Python | 5.0 | 53 | 4 | 8 |
| Python | 25.0 | 76 | 23 | 1 |
从数据的分布来看,9或10分表示强烈积极,7分及以下表示消极,8分表示中度积极。
4.3 二值化处理
我们可以将教程成功评价转换为二值变量。使用Pandas可以很容易地完成这个操作:
survey.Success >= 8
如果使用原始数组,可以使用scikit - learn的Binarizer类:
from sklearn.preprocessing import Binarizer
binary_rating = Binarizer(threshold=7.5)
success = binary_rating.fit_transform(survey[['Success']])
survey2 = survey.copy()
survey2['Success'] = success
4.4 分箱处理
对于参加者的高等教育年限,我们可以使用KBinsDiscretizer类将其分为“最少教育”、“中等教育”和“最多教育”三个类别,分别编码为0、1和2。
以下是具体的操作步骤:
1. 创建分箱器:
from sklearn.preprocessing import KBinsDiscretizer
edu_bin = KBinsDiscretizer(n_bins=3,
encode='ordinal',
strategy='quantile')
- 对Post_Secondary列进行分箱:
level = edu_bin.fit_transform(survey2[['Post_Secondary']])
survey3 = survey2.copy()
survey3['Education'] = level.astype(np.uint8)
survey3.drop('Post_Secondary', axis=1, inplace=True)
- 查看分箱的边界和每个箱中的数量:
print("Education cut-offs:")
print(edu_bin.bin_edges_[0], '\n')
print("Count per bin:")
print(survey3.Education.value_counts())
对于编程经验,我们可以使用不同的参数创建分箱器,将其分为5个相同数值范围的箱:
exp = KBinsDiscretizer(n_bins=5,
encode='ordinal',
strategy='uniform')
exp_level = exp.fit_transform(survey3[['Experience']])
survey4 = survey3.copy()
survey4['Experience'] = exp_level.astype(np.uint8)
4.5 年龄数据处理与分箱
在处理年龄数据时,我们发现数据中存在一些异常值,如3岁和99岁。我们将3岁的值修正为35岁。
以下是处理年龄数据并进行分箱的代码:
survey4.Age.describe()[['mean', 'min', 'max']]
survey[survey.Age < 10]
survey5 = survey4.copy()
survey5.loc[survey5.Age == 3, 'Age'] = 35
age_bin = KBinsDiscretizer(n_bins=3,
encode='onehot-dense',
strategy='quantile')
age = age_bin.fit_transform(survey5[['Age']])
age = age.astype(np.uint8).T
survey5 = survey5.assign(Young=age[0],
Mid_Age=age[1],
Old=age[2])
通过这些量化和分箱操作,我们可以将连续或有序的数据转换为更适合建模的形式,从而提高模型的性能。在实际应用中,我们需要根据数据的特点和任务的需求选择合适的量化和分箱方法。
5. 量化与分箱的进一步分析
5.1 不同分箱策略的效果
在前面的教程调查数据处理中,我们使用了不同的分箱策略,如对高等教育年限使用了基于分位数的分箱策略(
strategy='quantile'
),对编程经验使用了均匀分箱策略(
strategy='uniform'
)。不同的分箱策略会产生不同的效果,我们来详细分析一下。
高等教育年限分箱
使用基于分位数的分箱策略,将高等教育年限分为三个类别,代码如下:
from sklearn.preprocessing import KBinsDiscretizer
edu_bin = KBinsDiscretizer(n_bins=3,
encode='ordinal',
strategy='quantile')
level = edu_bin.fit_transform(survey2[['Post_Secondary']])
survey3 = survey2.copy()
survey3['Education'] = level.astype(np.uint8)
survey3.drop('Post_Secondary', axis=1, inplace=True)
print("Education cut-offs:")
print(edu_bin.bin_edges_[0], '\n')
print("Count per bin:")
print(survey3.Education.value_counts())
这种分箱策略会尽量使每个箱中的样本数量均衡。分箱边界如下:
[-12. 4.33333333 7. 23. ]
每个箱中的样本数量分布为:
| 教育水平编码 | 数量 |
| — | — |
| 2 | 44 |
| 0 | 39 |
| 1 | 33 |
编程经验分箱
使用均匀分箱策略,将编程经验分为5个相同数值范围的箱,代码如下:
exp = KBinsDiscretizer(n_bins=5,
encode='ordinal',
strategy='uniform')
exp_level = exp.fit_transform(survey3[['Experience']])
survey4 = survey3.copy()
survey4['Experience'] = exp_level.astype(np.uint8)
print("Experience cut-offs:")
print(exp.bin_edges_[0], '\n')
print("Count per bin:")
print(survey4.Experience.value_counts().sort_index())
均匀分箱策略会根据数据的取值范围平均划分箱。分箱边界如下:
[ 0. 5.4 10.8 16.2 21.6 27. ]
每个箱中的样本数量分布为:
| 经验等级编码 | 数量 |
| — | — |
| 0 | 93 |
| 1 | 14 |
| 2 | 4 |
| 3 | 1 |
| 4 | 4 |
可以看到,均匀分箱策略产生了严重不均衡的箱。在实际应用中,需要根据数据的分布和任务的需求选择合适的分箱策略。
5.2 编码方式的选择
在分箱过程中,我们使用了不同的编码方式,如对高等教育年限和编程经验使用了序数编码(
encode='ordinal'
),对年龄使用了独热编码(
encode='onehot-dense'
)。
序数编码
序数编码适用于数据具有自然顺序的情况,如高等教育年限和编程经验。编码后的数据保留了顺序信息,例如在高等教育年限分箱中,编码为0表示最少教育,编码为1表示中等教育,编码为2表示最多教育。
独热编码
独热编码适用于数据没有自然顺序,且不同类别之间是相互独立的情况,如年龄分箱。独热编码会将每个类别转换为一个二进制向量,向量中只有一个元素为1,其余元素为0。例如,在年龄分箱中,将年龄分为“Young”、“Mid_Age”和“Old”三个类别,使用独热编码后会生成三个新的列,分别表示这三个类别。
以下是年龄分箱使用独热编码的代码:
age_bin = KBinsDiscretizer(n_bins=3,
encode='onehot-dense',
strategy='quantile')
age = age_bin.fit_transform(survey5[['Age']])
age = age.astype(np.uint8).T
survey5 = survey5.assign(Young=age[0],
Mid_Age=age[1],
Old=age[2])
5.3 数据质量对分箱的影响
在处理数据时,数据质量会对分箱结果产生影响。例如,在教程调查数据中,高等教育年限出现了异常值23和 - 12,年龄出现了异常值3和99。我们对这些异常值进行了处理,将23归为最多教育类别,将 - 12归为最少教育类别,将3修正为35。
以下是处理年龄异常值的代码:
survey4.Age.describe()[['mean', 'min', 'max']]
survey[survey.Age < 10]
survey5 = survey4.copy()
survey5.loc[survey5.Age == 3, 'Age'] = 35
如果不处理这些异常值,可能会导致分箱结果不准确,影响后续的建模性能。
6. 综合应用与总结
6.1 综合应用流程
在实际的数据科学项目中,我们可以将前面介绍的降维、可视化、量化和分箱等技术综合应用。以下是一个综合应用的流程图:
graph LR
A[数据收集] --> B[数据清洗]
B --> C[特征选择与降维]
C --> D[可视化分析]
D --> E[量化与分箱]
E --> F[模型训练与评估]
6.2 各技术的作用
- 降维技术 :如主成分分析(PCA)、t - SNE和UMAP等,可以减少数据的维度,降低计算复杂度,同时保留数据的主要信息,有助于提高模型的训练效率和性能。
- 可视化技术 :PCA、t - SNE和UMAP等可视化技术可以将高维数据降维到二维或三维进行展示,帮助我们直观地理解数据的分布和结构,发现数据中的模式和规律。
- 量化与分箱技术 :可以将连续或有序的数据转换为离散的类别,减少数据的粒度,提高数据的可解释性,同时也有助于提高模型的性能。
6.3 注意事项
- 选择合适的技术 :在实际应用中,需要根据数据的特点和任务的需求选择合适的降维、可视化、量化和分箱技术。例如,对于线性可分的数据,PCA可能是一个不错的选择;对于非线性数据,t - SNE和UMAP可能会取得更好的效果。
- 处理异常值 :在进行数据处理时,需要注意处理异常值,避免异常值对数据处理结果产生影响。
- 评估模型性能 :在应用这些技术后,需要对模型的性能进行评估,确保技术的应用能够提高模型的性能。
通过综合应用这些技术,我们可以更好地处理高维数据,提高数据科学项目的效率和质量。在实际应用中,需要不断地尝试和调整,找到最适合数据和任务的方法。
数据降维与量化处理核心技术解析
超级会员免费看
873

被折叠的 条评论
为什么被折叠?



