小白的机器学习之路:Numpy探索

本文介绍了NumPy库在数据科学和机器学习中的应用,包括生成随机矩阵、数组操作、计算差值、堆叠生成矩阵及数组切片等核心知识点。

这是numpy教程系列的第二部分。 如果你还没有阅读过第一部分,我建议你先读一下。 在这个教程中,我将介绍Numpy中与数据科学和机器学习相关的重要知识点,也就是说,我不打算涵盖numpy所有的功能。

在前面的教程中,我们已经学习了np.array()np.arange()np.eye()
np.dot()np.shape()np.reshape()np.sum() 。如果你想马上就练习下Numpy,可以使用汇智网的Numpy在线运行环境

现在还是先导入numpy

import numpy as np

上面的语句告诉python,在后面的代码中,我们将使用np来引用numpy

np.random.rand()

先来看看使用numpy来生成随机值。 假设你想获得矩阵形式的随机值, 这很简单:

# 生成 2 x 3 随机矩阵
np.random.rand(2,3)
=======================
array([[ 0.2248368 ,  0.49652272,  0.76189091],
       [ 0.73520939,  0.48107188,  0.3883801 ]])

好吧,这可以扩展到多个维度吗? 当然可以! 这就是开发numpy的原因。

# 生成 12 x 13 随机矩阵
np.random.rand(12,13)
======================
array([[ 0.43385691,  0.15503296,  0.19860119,  0.65346609,  0.16774261,0.56058978,  0.84974275,  0.05887681,  0.27276929,  0.88750259,0.25141674,  0.05663906,  0.54186252],
...
[ 0.14066135,  0.34828447,  0.0780561 ,  0.00126867,  0.57958087,0.93641585,  0.70294758,  0.21712057,  0.24902555,  0.53284372,0.19795993,  0.69817631,  0.71156616]])

很容易就得到12x13的随机矩阵。 这很酷,对吧? np的确是一个出色的库。

如果想手动添加元素到数组中,该怎么办?

例如,对于下面的数组A:

A = np.append(A,19)
A
====================
array([ 5,  7,  9, 11, 13, 19])

如果想给A添加一个成员19,该怎么做?

np.append()满足的就是这个需求,它将元素添加到指定的数组中:

A = np.append(A,19)
A
===================
array([ 5,  7,  9, 11, 13, 19])

另一个小例子:

A = np.append(A,[3,55,34,553])
A
====================
array([  5,   7,   9,  11,  13,  19,   3,  55,  34, 553])

上面的例子是将一组元素添加到数组A中。所以不管是元素还是元素列表,都可以作为参数传入np.append()

注意np.append()不会更新原有的数组,因此需要捕捉其返回值来更新原始数组:

# A 不会自动更新
np.append(A,[3,55,34,553])

# 使用返回值更新A
A = np.append(A,[3,55,34,553])

这么明显又简单的事情,为什么我还要讲? 是这样:我吃过亏。我曾经花了数小时来搞清楚代码为什么失败,最终却发现都是这个微不足道的错误引起的:-(

如何计算邻接元素的差值?

例如,对于数组A:

A
===========
array([  5,   7,   9,  11,  13,  19,   3,  55,  34, 553])

我的问题是,在矩阵A中,我如何计算7-59-711-9? 换句话说,我怎样才能批量计算A [n + 1] -A [n]

np有一个内置方法np.diff()专用于解决这个问题。 它看起来像这样:

B = np.diff(A,n=1)
B
===============
array([  2,   2,   2,   2,   6, -16,  52, -21, 519])

如果简单做一下减法计算,就会注意到这个数组正好是A [n + 1] -A [n]。 这个数组比A要少一个元素。

如果继续在B上执行相同的np.diff(),最终会得到以下结果:

B = np.diff(B,n=1)
B
===================================================================
array([  0,   0,   0,   4, -22,  68, -73, 540])

也可以使用迭代参数n告诉np.diff()进行两次差分计算,而不必进行两次调用:

# parameter n indicates that this diff() must be run twice. 
np.diff(A,n=2)
===================================================================
array([  0,   0,   0,   4, -22,  68, -73, 540])

如何通过堆叠来生成矩阵/向量?

先定义三个列表:

# lets define 3 lists.
a = [1,2,3]
b = [4,5,6]
c = [7,8,9]

当我们谈到堆叠元素时,有两种思路:行堆叠和列堆叠。

列堆叠

# directly stack with lists passed in the same order.
np.vstack((a,b,c))
=====================
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

np.vstack((b,a,c))
=======================
array([[4, 5, 6],
       [1, 2, 3],
       [7, 8, 9]])

行堆叠

# stack with lists passed taking their columns as rows. 
np.vstack((a,b,c))
===================================================================
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]])

我们再回头来看看这些列表:

a = [1,2,3]
b = [4,5,6]
c = [7,8,9]

在这里,列方向是元素[1,4,7][2,5,8][3,6,9]。 问题是,如何让这些元素按行堆叠?

np.column_stack()

np.column_stack((a,b,c))
========================
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]])

np.column_stack((b,a,c))
========================
array([[4, 1, 7],
       [5, 2, 8],
       [6, 3, 9]])

完美!

如何从数组中选择子集合?

例如,在处理数组A时,我只想选中元素9,1113。 该怎么做?

A
==================
array([  5,   7,   9,  11,  13,  19,   3,  55,  34, 553])

这其实就是数组切片:指定开始序号和停止序号,切片选出在这两者之间(不包括停止序号)的所有元素。

例如:

A[2:5]  
===================
array([ 9, 11, 13])

在原数组中,成员9位于序号2,而成员13位于序号4。当进行数组切片时,要获取序号4处的元素,必须设置停止索引为5

从现在开始,我将把起始序号作为下界,停止序号作为上界。 因此,一般来说,切片可以被表述为:

A[lowerbound(inclusive): upperbound(exclusive)]

另一个例子:

A[0:3]
==============
array([5, 7, 9])

现在谈谈广播

广播(broadcasting)是numpy最棒的特性之一,可以将一个操作扩展到矩阵中的所有元素。

什么意思?

A
================
array([  5,   7,   9,  11,  13,  19,   3,  55,  34, 553])

如果我想给A的所有元素加1,该怎么做? 很自然地,我们可能会尝试下面的代码:

# 创建目标数组K
K = np.array([])

# 遍历A中所有元素,加1后设置为K的元素
# and append the new value to the array.
for e in A:
    K = np.append(K,e+1)

# 打印目标数组K
K
======================
array([  6,   8,  10,  12,  14,  20,   4,  56,  35, 554])

很可能每个人都会认可这种看起来相当自然的做法。 问题是,这种实现“耗时且效率低下”。

真的吗? 为什么这是低效的?

这就是广播的作用。 我可以只用一行代码实现同样的功能,而不需要任何for循环,如下所示:

K = A+1
K
===============
array([  6,   8,  10,  12,  14,  20,   4,  56,  35, 554])

但是这是什么原理?

numpy在内部实现中,可以根据需要来进行操作元素匹配:

# numpy实现广播的原理:展开
A+[1,1,1,1,1,1,1,1,1,1]

另一个例子:

A*-1
=============
array([  -5,   -7,   -9,  -11,  -13,  -19,   -3,  -55,  -34, -553])

注意整个数组现在带有减号。 这就是广播。

现在你知道了,如果想处理一个numpy数组中的所有元素,不一定需要使用for循环,广播真的很酷。

如果你喜欢这篇文章,记得关注我的头条号:新缸中之脑!

原文:Introduction to Numpy -2 : An absolute beginners guide to Machine Learning and Data science.

<think>好的,用户想了解机器学习的基础知识,特别是入门教程。首先,我需要根据提供的引用内容来构建回答的结构,确保信息准确且相关。让我先看看用户提供的引用资料。 引用[1]提到线性代数对理解机器学习理论很重要,尤其是深度学习。但刚入门时可以不需要掌握。所以,在基础知识部分,我应该提到数学基础,但也要说明初期不需要深入,避免吓到初学者。 引用[2]给出了机器学习算法实现的流程:评估问题、准备数据、检查算法、实验结果、深入最佳算法。这部分可以整理为学习路径,帮助用户一步步进行。 引用[3]是关于学习率的注意事项,这可能属于模型训练中的关键点,可以放在实践建议里,或者在优化部分提到。 引用[4]展示了KNN分类器的代码示例,还有决策树的例子。这说明在工具与框架部分,需要提到Scikit-learn这样的库,并给出代码实例,方便用户动手实践。 用户的问题是关于机器学习入门教程,所以需要从基础概念、数学基础、学习路径、工具框架、实践建议等方面组织内容。同时,用户要求生成相关问题,这部分需要根据回答内容提出相关的问题,比如数学基础的重要性、学习路径的步骤、常用工具等。 还要注意系统级指令,比如使用中文,数学公式用$...$,独立公式用$$...$$,并且正确使用LaTeX语法。例如,在提到线性代数时,可以写出向量表示为$\mathbf{x}$,矩阵乘法为$A \cdot B$。如果有独立公式,比如线性回归的损失函数,应该用$$...$$单独成段。 需要确保回答结构清晰,分步骤讲解。同时,引用内容要自然地插入到回答中,并在末尾添加引用标识。例如,在提到学习率时,引用[3],在提到流程时引用[2]。 现在需要检查是否覆盖了用户的需求:机器学习的基础知识、入门教程。可能用户是刚开始学习,需要简明扼要的解释,避免过多复杂理论,强调实践和步骤。此外,相关问题要围绕入门可能遇到的疑问,比如数学要求、学习步骤、工具选择、常见挑战等。 最后,确保回答中的代码示例正确,比如引用[4]中的KNN代码,可能需要简要说明代码的作用,让用户了解如何使用库来实现算法。</think>### 机器学习入门教程分步指南 #### 一、基础概念与核心组成 1. **机器学习定义** 通过算法使计算机从数据中学习规律,无需显式编程。例如,分类任务中模型自动识别特征与标签的关系。 2. **三大学习范式** - 监督学习:使用带标签数据训练,如线性回归、KNN分类(示例代码见引用[4]) - 无监督学习:发现无标签数据中的结构,如聚类 - 强化学习:通过环境反馈优化决策,如游戏AI #### 二、数学基础与工具准备 1. **关键数学领域** - 线性代数:向量$\mathbf{x}$、矩阵乘法$A \cdot B$(长期学习必备,但初期可暂缓[^1]) - 概率统计:条件概率$P(Y|X)$、均值方差 - 微积分:梯度计算$\frac{\partial L}{\partial w}$ 2. **开发环境搭建** - Python + Jupyter Notebook - 库安装命令: ```bash pip install numpy pandas matplotlib scikit-learn ``` #### 三、系统化学习路径(引用[2]流程) 1. **问题定义阶段** - 明确任务类型(分类/回归/聚类) - 评估数据可用性与质量 2. **数据预处理流程** ```python from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(X) ``` 3. **算法实验方法论** | 算法类型 | Scikit-learn类 | 适用场景 | |---------------|-------------------------|-------------------| | K近邻 | KNeighborsClassifier | 小规模分类 | | 决策树 | DecisionTreeClassifier | 可解释性要求高 | | 随机森林 | RandomForestClassifier | 高精度需求 | 4. **模型评估标准** - 分类:准确率$\frac{TP+TN}{Total}$ - 回归:MSE $\frac{1}{n}\sum(y_i-\hat{y}_i)^2$ #### 四、典型问题解决示例(手写数字识别) 1. **数据加载与探索** ```python from sklearn.datasets import load_digits digits = load_digits() plt.matshow(digits.images[0]) # 可视化样本 ``` 2. **管道化建模** ```python from sklearn.pipeline import make_pipeline pipe = make_pipeline( StandardScaler(), PCA(n_components=0.95), RandomForestClassifier() ) ``` 3. **超参数优化实践** ```python from sklearn.model_selection import GridSearchCV params = {'n_estimators': [50, 100]} grid_search = GridSearchCV(pipe, params) grid_search.fit(X_train, y_train) ``` #### 五、持续提升建议 1. **避免的常见误区** - 过早优化:引用[2]强调先建立基线模型 - 忽视数据质量:垃圾数据导致错误结论 2. **学习率设置技巧** 使用学习率衰减策略,如初始值设为0.1,每5个epoch减半[^3] 3. **理论深化方向** - 推导逻辑回归的梯度公式 - 理解VC维与泛化误差关系 §§ 1. 如何选择机器学习项目的评估指标? 2. 数据标准化与归一化的区别是什么? 3. 遇到模型过拟合时应采取哪些措施? 4. 怎样通过学习曲线诊断模型问题? 5. 不同优化器(如Adam/SGD)的适用场景有何差异? [^1]: 线性代数中的概念是理解机器学习理论所必需的基础知识,尤其是对那些处理深度学习算法的人而言。在刚接触机器学习时,你可以不需要掌握线性代数。 [^2]: 无论什么时候实现机器学习算法,推荐采用如下流程来开始:评估你的问题->准备数据->检查各种机器学习算法->检验实验结果->深入了解性能最好的算法。 [^3]: 注意,我们选择学习率时要避免过大或过小,学习率太大,会出现振荡甚至梯度爆炸的现象,学习率过小,收敛速度会变慢。 [^4]: KNN分类器示例代码展示了Scikit-learn的标准建模流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值