专栏名称: 新语数据故事汇
《新语数据故事汇,数说新语》科普数据科学、讲述数据故事,深层次挖掘数据价值。
目录
相关文章推荐
商学院  ·  新刊热卖 | ... ·  18 小时前  
商学院  ·  新刊热卖 | ... ·  18 小时前  
51好读  ›  专栏  ›  新语数据故事汇

数据科学家们必须掌握的五种数据结构

新语数据故事汇  · 公众号  ·  · 2024-09-08 19:09

正文

在机器学习(ML)和数据科学过程中,算法模型的性能和可扩展性往往取决于所选择的底层数据结构。无论是处理大型数据集、管理复杂关系,还是优化算法效率,选择合适的数据结构都至关重要。

数组/矩阵(Arrays)、堆(heaps)、哈希表(hash tables)、树(trees)和图(graphs):这些不仅是理论概念,更是实用工具,能使模型运行更快、占用更少的内存,并处理更复杂的任务。

接下来介绍一些这些关键的数据结构,揭示它们在各种机器学习应用中的重要作用,并探讨如何通过它们提升模型的能力。

数组和矩阵(Arrays and Matrices)

数组和矩阵是计算机科学和机器学习中最基础的数据结构之一。

数组是存储在连续内存块中的元素集合,通常元素类型相同。数组是按索引访问的,这意味着每个元素都可以通过其索引(即数组中的位置)进行访问。

矩阵是二维数组,按照行和列来组织数据。在机器学习中,矩阵对于表示数据至关重要,特别是在处理表格数据、图像或多维数据时。数组通常表示单一向量(即一维数据),而矩阵则表示更复杂的关系(二维数据),这使得它们在各种应用场景中具有不可替代的价值。

数学表示法:

一个具有 m 行和 n 列的矩阵 A 可以表示为:

机器学习中的应用包括数据表示、矩阵运算

  1. 数据表示(特征向量、图像):

特征向量 :在机器学习中通常将数据表示为向量。例如,可以将具有 n 个特征(变量)的数据集描述为一个 n 维向量:

在机器学习任务中,特征向量广泛用于输入模型,例如线性回归、支持向量机(SVM)和神经网络中的输入层,它们通过特征向量进行运算和预测。

图像表示 :在计算机视觉任务中,图像通常表示为二维矩阵,其中每个元素表示图像像素的值(灰度或 RGB 值)。

2. 矩阵运算在线性代数中的应用:

矩阵在机器学习中的许多操作中占据核心地位,尤其是线性代数,这几乎是整个领域的基础。

矩阵乘法 :最常见的操作之一就是矩阵乘法。给定矩阵 A 是一个 m×n 的矩阵,矩阵 B 是一个 n×p的矩阵,它们的乘积 C 是一个 m×p 的矩阵,其表示方式为:

即矩阵 C 的第 i 行第 j 列元素是通过矩阵 A 的第 i 行与矩阵 B 的第 j 列的元素逐项相乘并相加得到的。

矩阵乘法在机器学习中的许多算法中扮演着重要角色,例如神经网络中的前向传播和反向传播、线性回归中的最小二乘法等。通过高效的矩阵运算,可以加速模型的训练过程,尤其是在处理大型数据集和多维矩阵时。

线性回归示例 :在线性回归中,目标是找到一个系数向量 β,以最小化预测值与目标值之间的差异。该模型可以表示为:

其中,X 是输入数据矩阵,β 是系数向量,ϵ 是误差项,y 是目标值向量。为了估计 β,我们使用 正规方程 ,其公式为:

这个公式利用矩阵运算求解最优的回归系数,从而使得预测值与真实值之间的误差最小化。这是线性回归模型的核心计算之一,通过矩阵的转置、乘法和逆矩阵操作,找到最佳拟合参数。

import numpy as np
# Example datasetX = np.array([[1, 1], [1, 2], [2, 2], [2, 3]]) # Feature matrixy = np.dot(X, np.array([1, 2])) + 3 # Target vector
# Add a column of ones to X to account for the intercept termX = np.hstack([np.ones((X.shape[0], 1)), X])
# Calculate beta using the normal equationbeta = np.linalg.inv(X.T @ X) @ X.T @ y
print("Estimated coefficients:", beta)

堆(heaps)

堆是一种特殊的基于树的数据结构,满足 堆属性 。在最大堆中,对于任何给定节点 i , i 的值大于或等于其子节点的值。相反,在最小堆中,i 的值小于 等于 其子节点的值。此属性确保根节点始终包含最大(最大堆)或最小(最小堆)元素,使堆非常适合实现优先级队列。

通常将堆实现为二叉树,其中每个父节点最多有两个子节点。经常用数组表示堆的结构,这样就可以很容易地使用索引上的简单算法来导航父子关系。

最大堆性质: 对于最大堆,每个节点的值都大于或等于其子节点的值:

最小堆性质: 对于最小堆,每个节点的值小于或等于其子节点的值:

堆(heaps)在机器学习中常常用于路径规划和查找。

1.类似 A *搜索的算法中的优先级队列:

在 AI 规划和路径查找算法(例如 A* ) 中,堆用于高效地实现优先级队列。优先级队列按优先级对元素进行排序,允许算法不断扩展最有希望的节点。通常使用最小堆,其中成本最低的节点位于根部并且可以不断访问。

import heapq# Example graph (as an adjacency list)graph = {   'A': [('B', 1), ('C', 4)],            'B': [('A', 1), ('C', 2), ('D', 5)],            'C': [('A', 4), ('B', 2), ('D', 1)],            'D': [('B', 5), ('C', 1)] }
# A* search functiondef a_star(graph, start, goal, h): # Priority queue, initialized with the start node pq = [(0 + h(start), 0, start, [])] # (f = g + h, g, node, path) heapq.heapify(pq) while pq: (f, g, current, path) = heapq.heappop(pq) # Path to the current node path = path + [current] if current == goal: return path, f # Return the found path and its total cost for (neighbor, cost) in graph[current]: heapq.heappush(pq, (g + cost + h(neighbor), g + cost, neighbor, path)) return None # If no path is found
# Heuristic function (for simplicity, using zero heuristic as an example)def h(node): return 0
# Find path from A to Dpath, cost = a_star(graph, 'A', 'D', h)print("Path:", path, "Cost:", cost)

在上面的示例中,最小堆存储了 A* 搜索算法中节点的各自成本(优先级)。堆确保首先扩展成本最低的节点,从而优化搜索过程。

2. 聚类算法(例如K-means)中大型数据集的有效管理:

堆还可用于聚类算法(如 K-means),以便在迭代过程中高效管理和更新质心。在管理大量数据点时,堆有助于优化质心的选择和更新,尤其是在确定离数据点最近的质心时。

示例:使用堆进行 K-means 初始化 (K-means++)

K-means++ 是一种初始化技术,用于选择初始质心以加快收敛速度。堆可以有效地管理点到其最近质心的距离。

import numpy as np
def initialize_centroids(X, k): centroids = [] centroids.append(X[np.random.randint(X.shape[0])]) for _ in range(1, k): distances = np.array([min([np.linalg.norm(x - c) for c in centroids]) for x in X]) heap = [(dist, i) for i, dist in enumerate(distances)] heapq.heapify(heap) # Weighted random selection of the next centroid total_dist = sum(distances) r = np.random.uniform(0, total_dist) cumulative_dist = 0 for dist, i in heap: cumulative_dist += dist if cumulative_dist >= r: centroids.append(X[i]) break return np.array(centroids)
# Example datasetX = np.array([[1, 2], [1, 4], [3, 2], [5, 6], [7, 8], [9, 10]])centroids = initialize_centroids(X, 2)print("Initial centroids:\n", centroids)

在 k-means++ 中初始化质心时使用堆来管理数据点与其最近质心之间的距离。这确保选择质心以最大化它们之间的最小距离,从而获得更好的聚类结果。

哈希表(hash tables)

哈希 是一种实现关联数组的数据结构,关联数组是一种可以将键映射到值的结构。它建立在 键值 对的概念之上,其中每个键都是唯一的并与特定值相关联。哈希表因其能够执行快速数据检索、插入和删除操作而广泛应用于计算领域。

哈希表的效率来自于 哈希函数 ,它获取一个键并计算数组(通常称为哈希表)中的索引(哈希码)。然后将键值对存储在哈希码指示的数组中。当需要检索某个值时,将相同的哈希函数应用于该键,然后可以使用计算出的索引快速访问相应的值。

哈希函数:

良好的哈希函数可确保:

  • 哈希码均匀分布,最大限度地减少了多个键哈希到同一索引的机会(即 冲突 )。

  • 该函数是确定性的,这意味着相同的键将始终产生相同的哈希码。

数学表示:

给定一个键 k 和一个哈希函数 h ,索引 i (键值对在哈希表中的位置)由以下公式给出:

1.实现大型数据集的高效查找:

当您需要高效地从大型数据集中检索数据时,哈希表非常方便。例如,在大量用户交互(例如点击、浏览、购买)数据集中,哈希表可以快速访问与特定用户相关的交互。

# Example dataset: user interactions with itemsuser_interactions = {    'user1': ['item1', 'item2', 'item3'],    'user2': ['item2', 'item4'],    'user3'






请到「今天看啥」查看全文