Python 全栈 60 天精通之路

Day 15:8 个数据分析、机器学习和深度学习包和框架和入门案例总结

发布日期:2022年3月12日 18:02 阅读: 288 访问: 288

五分钟入门 8 个数据分析、机器学习和深度学习包和框架和入门案例总结,提供 8 个数据分析和机器学习常用的工具包。NumPyNumPy 是基于 Python 的开源数值计算扩展库,用来存储和处理大型矩阵。相比于 Python 自身的嵌套列表(nested list structure)结构要高效得多。NumPy 数组结构也能用来表示

五分钟入门 8 个数据分析、机器学习和深度学习包和框架和入门案例总结,提供 8 个数据分析和机器学习常用的工具包。

NumPy

NumPy 是基于 Python 的开源数值计算扩展库,用来存储和处理大型矩阵。

相比于 Python 自身的嵌套列表(nested list structure)结构要高效得多。

NumPy 数组结构也能用来表示矩阵(matrix),详情参考:

https://numpy.org/

主要功能包括:

  1. N 维数组对象 Array
  2. 成熟的广播机制
  3. 能够解决线性代数、随机数生成数相关问题

NumPy 最基本的数据结构 array,下面是关于它的基本操作。

首先,导入 NumPy 包:

In [1]: import numpy as np

NumPy 中,array 函数将 Python 的 list 对象包装为 array:

In [9]: x = np.array([[2, 1], [1, 2]])

In [10]: x
Out[10]:
array([[2, 1],
       [1, 2]])

求 x 的转置矩阵:

In [11]: xt = x.transpose()

In [12]: xt
Out[12]:
array([[2, 1],
       [1, 2]])

方便的赋值操作:

xt[0, 0] =1.0

dot 操作求两个矩阵的乘积:

In [13]: x2 = xt.dot(x)

In [14]: x2
Out[14]:
array([[5, 4],
       [4, 5]])

求逆矩阵,需要导入另一个模块 linalg:

In [19]: import numpy.linalg as lg

In [20]: lg.inv(x2)
Out[20]:
array([[ 0.55555556, -0.44444444],
       [-0.44444444,  0.55555556]])

SciPy

SciPy 基于 Python,是用于数学计算的工具包。详情参考:

https://www.scipy.org/

案例:绘制常见的两种概率分布。

In [21]: from scipy.stats import norm, uniform
    ...: import numpy as np

写一个专门绘图用的装饰器。

首先导入所需要的包:

import matplotlib.pyplot as plt
from functools import wraps

绘图装饰器,带有四个参数,分别表示:legend 的 2 类说明文字、y 轴 label、保存的 PNG 文件名称。

# 定义带四个参数的画图装饰器
def my_plot(label0=None, label1=None, ylabel='probability density function', fn=None):
    def decorate(f):
        @wraps(f)
        def myplot():
            fig = plt.figure(figsize=(16, 9))
            ax = fig.add_subplot(111)
            x, y, y1 = f()
            ax.plot(x, y, linewidth=2, c='r', label=label0)
            ax.plot(x, y1, linewidth=2, c='b', label=label1)
            ax.legend()
            plt.ylabel(ylabel)
            # plt.show()
            plt.savefig('./img/%s' % (fn,))
            plt.close()
        return myplot
    return decorate

均匀分布函数 unif:

@my_plot(label0='b-a=1.0', label1='b-a=2.0', fn='uniform.png')
def unif():
    x = np.arange(-0.01, 2.01, 0.01)
    y = uniform.pdf(x, loc=0.0, scale=1.0)
    y1 = uniform.pdf(x, loc=0.0, scale=2.0)
    return x, y, y1

调用 unif(),绘制均匀分布的概率密度曲线:

二项分布

@my_plot(label0='n=50,p=0.3', label1='n=50,p=0.7', fn='binom.png', ylabel='probability mass function')
def bino():
    x = np.arange(50)
    n, p, p1 = 50, 0.3, 0.7
    y = binom.pmf(x, n=n, p=p)
    y1 = binom.pmf(x, n=n, p=p1)
    return x, y, y1

调用 bino(),绘制二项分布概率密度图:

红色曲线表示发生一次概率为 0.3,重复 50 次的密度函数,二项分布期望值为 0.3*50 = 15 次。

看到这 50 次实验,很可能出现的次数为 10~20。

Pandas

Pandas 是 Python 中,功能强大的数据分析库。提供关于数据分析高级的数据结构,各种各样的分析工具,确保整个数据处理的过程更加容易。详情参考:

https://pandas.pydata.org/

Pandas 两大数据结构:

  • 一维 Series
  • 二维 DataFrame

创建 Series:

In [32]: s1 = pd.Series( [3,5,7])

In [33]: s1
Out[33]:
0    3
1    5
2    7
dtype: int64

指定 index、name:

In [34]: s2 = pd.Series( [3,5,7], index = list('ABC'),name='s3' )

In [35]: s2
Out[35]:
A    3
B    5
C    7
Name: s3, dtype: int64

通过嵌套列表,创建 DataFrame:

In [36]: df = pd.DataFrame([[9,0,1],[7,3,10]],index=['a','b'],columns=['A','B','C'])

In [37]: df
Out[37]:
   A  B   C
a  9  0   1
b  7  3  10

通过字典,创建 DataFrame:

In [38]: df = pd.DataFrame({'A':[9,7],'B':[0,3],'C':[1,10]},index=['a','b'])

In [39]: df
Out[39]:
   A  B   C
a  9  0   1
b  7  3  10

Matplotlib

Matplotlib 是 Python 中非常强大的 2D 绘图工具。提供方便易用的绘图接口,能使用在 Python 脚本,IPython shell、Jupyter Notebook、Web 应用服务器等。详情参考:

https://matplotlib.org/

下面的案例,绘制三类折线图。

首先,导入所需要的包:

import numpy as np
import matplotlib.pyplot as plt

其次,创建画图 fig 和 axes:

def setup_axes():
    fig, axes = plt.subplots(ncols=3, figsize=(6.5,3))
    for ax in fig.axes:
        ax.set(xticks=[], yticks=[])
    fig.subplots_adjust(wspace=0, left=0, right=0.93)
    return fig, axes

生成数据 x,创建 fig、axes:

x = np.linspace(0, 10, 100)
fig, axes = setup_axes()
for ax in axes:
    ax.margins(y=0.10)

执行上述代码,生成空白图:

子图 1,绘制多条线,颜色系统分配:

for i in range(1, 6):
    axes[0].plot(x, i * x)

子图 2 ,展示线的不同 linestyle:

for i, ls in enumerate(['-', '--', ':', '-.']):
    axes[1].plot(x, np.cos(x) + i, linestyle=ls)

子图 3,展示线的不同 linestyle 和 marker:

for i, (ls, mk) in enumerate(zip(['', '-', ':'], ['o', '^', 's'])):
    axes[2].plot(x, np.cos(x) + i * x, linestyle=ls, marker=mk, markevery=10)

Seaborn

Seaborn 是一个基于 Matplotlib 的 Python 数据可视化库,提供绘制更加高层和优美的图形接口。详情参考:

http://seaborn.pydata.org/

如下,绘制模型拟合后的残差图,y 值添加一个正态分布的误差。

使用 Seaborn 绘图非常方便,所写代码更少。

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

sns.set(style="whitegrid")

rs = np.random.RandomState(1)
x = rs.normal(2, 0.1, 50)
y = 2 + 1.6 * x + rs.normal(0, 0.1, 50)

sns.residplot(x, y, lowess=True, color="orange")
plt.show()

从残差图看出,y 值误差符合均值 0、方差 0.1 的正态分布规律。

scikit-learn

scikit-learn 是适用于数据处理和机器学习处理非常强大的库。提供数据降维、回归、聚类、分类等功能,是机器学习从业者的必备库之一。详情参考:

https://scikit-learn.org/

案例:鸢尾属植物数据集(iris)分类。

鸢尾属植物数据集一共有 4 个特征,target 值有 3 类,每一类都有 50 个样本。

四维数据集为了在二维平面内展示方便,只选取其中两个维度。

如下面数据集,选择特征:sepallength、petallength、species 是 target 值。

     sepal_length  petal_length    species
0             5.1           1.4     setosa
1             4.9           1.4     setosa
2             4.7           1.3     setosa
3             4.6           1.5     setosa
4             5.0           1.4     setosa
..            ...           ...        ...
145           6.7           5.2  virginica
146           6.3           5.0  virginica
147           6.5           5.2  virginica
148           6.2           5.4  virginica
149           5.9           5.1  virginica

如下所示,绘制出一对特征的数据分布矩阵图,点的颜色表示分类值。

矩阵图主对角线,两幅子图分表表示特征 sepallength、petallength 取值的概率分布图。

绘制下图的代码:

from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import seaborn as sns

sns.set(style="ticks")

df = sns.load_dataset("iris")
df02 = df.iloc[:,[0,2,4]] # 选择一对特征
print(df02)
sns.pairplot(df02, hue="species")
plt.show()

从上图看出,选取的一对特征,species 分布具有一定规律。target 值给定,因此是有监督分类任务。

选择一个基础的分类算法——决策树模型,学习此任务的分类模型。

导入树模型 tree:

from sklearn import tree

创建决策树分类器:

clf = tree.DecisionTreeClassifier()

每类植物抽样 3/5 数据做训练,2/5 做预测。

train_index = [i for i in range(150) if i<30 or 50<=i<80 or 100<=i<130]
test_index = [i for i in range(150) if 30<=i<50 or 80<=i<100 or 130<=i<150]

train_data, train_target = df02.iloc[train_index,[0,1]],df02.iloc[train_index,2]

test_data, test_target = df02.iloc[test_index,[0,1]],df02.iloc[test_index,2]

训练模型:

clf = clf.fit(train_data, train_target)
print(clf)
# 结果
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
                       max_features=None, max_leaf_nodes=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, presort=False,
                       random_state=None, splitter='best')

在数据上做预测:

test_val = clf.predict(test_data)
print(test_val)
# 结果
['setosa' 'setosa' 'setosa' 'setosa' 'setosa' 'setosa' 'setosa' 'setosa'
 'setosa' 'setosa' 'setosa' 'setosa' 'setosa' 'setosa' 'setosa' 'setosa'
 'setosa' 'setosa' 'setosa' 'setosa' 'versicolor' 'versicolor'
 'versicolor' 'virginica' 'versicolor' 'versicolor' 'versicolor'
 'versicolor' 'versicolor' 'versicolor' 'versicolor' 'versicolor'
 'versicolor' 'versicolor' 'versicolor' 'versicolor' 'versicolor'
 'versicolor' 'versicolor' 'versicolor' 'virginica' 'virginica'
 'virginica' 'virginica' 'virginica' 'virginica' 'virginica' 'virginica'
 'versicolor' 'virginica' 'virginica' 'virginica' 'virginica' 'virginica'
 'virginica' 'virginica' 'versicolor' 'virginica' 'virginica' 'virginica']

预测精度 95%。

right = [i for i, j in zip(test_val,test_target) if i==j] 
percent = len(right) / len(test_target)
print(percent)  # 0.95

TensorFlow

TensorFlow 由 Google 与 Brain Team 合作开发,是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。

节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

详情参考:

http://www.tensorfly.cn/

案例:使用 TensorFlow 做线性回归。

#global_variables_initializer 初始化 Variable 等变量
import tensorflow as tf

sess = tf.Session()

init = tf.global_variables_initializer()

sess.run(init)

print("w=", sess.run(w),"b=",sess.run(b),sess.run(loss))

#迭代 20 次 train

for step in range(20):

    sess.run(train)

    print("w=", sess.run(w),"b=",sess.run(b),sess.run(loss))

#写入磁盘,提供 tensorboard 在浏览器中展示用

writer = tf.summary.FileWriter("./mytmp",sess.graph)

打印下 w 和 b,损失值的变化情况,可以看到损失值从 0.24 降到 0.0008。

拟合结果:

PyTorch

PyTorch 是使用 GPU 和 CPU 优化的深度学习张量库,也是深度学习的重要的一个库。详情参考:

https://pytorch.org/

In [9]: import torch 

In [10]: a = torch.ones(10)  
In [11]: b = torch.ones(10)  

In [11]: a + b # 矢量相加
Out[11]: tensor([2., 2., 2., 2., 2., 2., 2., 2., 2., 2.])  

小结

今天与大家一起学习了 8 个数据分析、机器学习和深度学习的常见包和框架。大部分包介绍时,还配备了入门的案例,方便大家快速形成一个使用它们的初步印象。