头图

全套笔记资料代码移步: 前往gitee仓库查看

感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~


全套教程部分目录:


部分文件图片:

Introduction

机器学习算法课程定位、目标

定位

  • 课程以算法、案例为驱动的学习,伴随浅显易懂的数学知识
  • 作为人工智能领域的提升课程,掌握更深更有效的解决问题技能

目标

  • 掌握机器学习常见算法原理
  • 应用Scikit-learn实现机器学习算法的应用,
  • 结合场景解决实际问题

K-近邻算法

学习目标

  • 掌握K-近邻算法实现过程
  • 知道K-近邻算法的距离公式
  • 知道K-近邻算法的超参数K值以及取值问题
  • 知道kd树实现搜索的过程
  • 应用KNeighborsClassifier实现分类
  • 知道K-近邻算法的优缺点
  • 知道交叉验证实现过程
  • 知道超参数搜索过程
  • 应用GridSearchCV实现算法参数的调优

1.1 K-近邻算法简介

学习目标

  • 目标

    • 了解什么是KNN算法
    • 知道KNN算法求解过程

1 什么是K-近邻算法

  • 根据你的“邻居”来推断出你的类别

1.1 K-近邻算法(KNN)概念

K Nearest Neighbor算法又叫KNN算法,这个算法是机器学习里面一个比较经典的算法, 总体来说KNN算法是相对比较容易理解的算法

  • 定义

如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

来源:KNN算法最早是由Cover和Hart提出的一种分类算法
  • 距离公式

两个样本的距离可以通过如下公式计算,又叫欧式距离 ,关于距离公式会在后面进行讨论

img

1.2 电影类型分析

假设我们现在有几部电影

image-20190316204421392

其中? 9号电影不知道类别,如何去预测?我们可以利用K近邻算法的思想

image-20190316204448303

分别计算每个电影和被预测电影的距离,然后求解

image-20190316204517137

1.3 KNN算法流程总结

1)计算已知类别数据集中的点与当前点之间的距离

2)按距离递增次序排序

3)选取与当前点距离最小的k个点

4)统计前k个点所在的类别出现的频率

5)返回前k个点出现频率最高的类别作为当前点的预测分类

2 小结

  • K-近邻算法简介【了解】

    • 定义:就是通过你的"邻居"来判断你属于哪个类别
    • 如何计算你到你的"邻居"的距离:一般时候,都是使用欧氏距离

1.2 k近邻算法api初步使用

学习目标

  • 目标

    • 了解sklearn工具的优点和包含内容
    • 应用sklearn中的api实现KNN算法的简单使用

  • 机器学习流程复习:

image-20190312180135881

  • 1.获取数据集
  • 2.数据基本处理
  • 3.特征工程
  • 4.机器学习
  • 5.模型评估

1 Scikit-learn工具介绍

scikitlearn

  • Python语言的机器学习工具
  • Scikit-learn包括许多知名的机器学习算法的实现
  • Scikit-learn文档完善,容易上手,丰富的API
  • 目前稳定版本0.19.1

1.1 安装

pip3 install scikit-learn==0.19.1

安装好之后可以通过以下命令查看是否安装成功

import sklearn
  • 注:安装scikit-learn需要Numpy, Scipy等库

1.2 Scikit-learn包含的内容

image-20190225170704470

  • 分类、聚类、回归
  • 特征工程
  • 模型选择、调优

2 K-近邻算法API

  • sklearn.neighbors.KNeighborsClassifier(n_neighbors=5)

    • n_neighbors:int,可选(默认= 5),k_neighbors查询默认使用的邻居数

3 案例

3.1 步骤分析

  • 1.获取数据集
  • 2.数据基本处理(该案例中省略)
  • 3.特征工程(该案例中省略)
  • 4.机器学习
  • 5.模型评估(该案例中省略)

3.2 代码过程

  • 导入模块
from sklearn.neighbors import KNeighborsClassifier
  • 构造数据集
x = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
  • 机器学习 -- 模型训练
  
  
# 实例化API
  
  
estimator = KNeighborsClassifier(n_neighbors=1)
  
  
# 使用fit方法进行训练
  
  
estimator.fit(x, y)

estimator.predict([[1]])

4 小结

  • sklearn的优势:

    • 文档多,且规范
    • 包含的算法多
    • 实现起来容易
  • knn中的api

    • sklearn.neighbors.KNeighborsClassifier(n_neighbors=5)

问题

1.距离公式,除了欧式距离,还有哪些距离公式可以使用?

2.选取K值的大小?

3.api中其他参数的具体含义?

K-近邻算法

学习目标

  • 掌握K-近邻算法实现过程
  • 知道K-近邻算法的距离公式
  • 知道K-近邻算法的超参数K值以及取值问题
  • 知道kd树实现搜索的过程
  • 应用KNeighborsClassifier实现分类
  • 知道K-近邻算法的优缺点
  • 知道交叉验证实现过程
  • 知道超参数搜索过程
  • 应用GridSearchCV实现算法参数的调优

1.3 距离度量

学习目标

  • 目标

    • 了解距离公式的基本性质
    • 知道机器学习中常见的距离计算公式

1 距离公式的基本性质

在机器学习过程中,对于函数<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>d</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo>(</mo><mi mathvariant="normal">.</mi><mo separator="true">,</mo><mi mathvariant="normal">.</mi><mo>)</mo></mrow><annotation encoding="application/x-tex">dist(., .)</annotation></semantics></math></span><span aria-hidden="true" class="katex-html"><span class="strut" style="height:0.75em;"></span><span class="strut bottom" style="height:1em;vertical-align:-0.25em;"></span><span class="base textstyle uncramped"><span class="mord mathit">d</span><span class="mord mathit">i</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mopen">(</span><span class="mord mathrm">.</span><span class="mpunct">,</span><span class="mord mathrm">.</span><span class="mclose">)</span></span></span></span>,若它是一"距离度量" (distance measure),则需满足一些基本性质:

  • 非负性:<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>d</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo>(</mo><msub><mi>X</mi><mi>i</mi></msub><mo separator="true">,</mo><msub><mi>X</mi><mi>j</mi></msub><mo>)</mo><mo>></mo><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">dist(X_i,X_j) >= 0</annotation></semantics></math></span><span aria-hidden="true" class="katex-html"><span class="strut" style="height:0.75em;"></span><span class="strut bottom" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="base textstyle uncramped"><span class="mord mathit">d</span><span class="mord mathit">i</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mopen">(</span><span class="mord"><span class="mord mathit" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:-0.07847em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight">i</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mpunct">,</span><span class="mord"><span class="mord mathit" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:-0.07847em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight" style="margin-right:0.05724em;">j</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mclose">)</span><span class="mrel">></span><span class="mrel">=</span><span class="mord mathrm">0</span></span></span></span>;
  • 同一性:<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>d</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo>(</mo><msub><mi>x</mi><mi>i</mi></msub><mo separator="true">,</mo><msub><mi>x</mi><mi>j</mi></msub><mo>)</mo><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">dist(x_i,x_j)=0</annotation></semantics></math></span><span aria-hidden="true" class="katex-html"><span class="strut" style="height:0.75em;"></span><span class="strut bottom" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="base textstyle uncramped"><span class="mord mathit">d</span><span class="mord mathit">i</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mopen">(</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight">i</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mpunct">,</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight" style="margin-right:0.05724em;">j</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mclose">)</span><span class="mrel">=</span><span class="mord mathrm">0</span></span></span></span>。当且仅当<span class="katex"><span class="katex-mathml"><math><semantics><mrow><msub><mi>X</mi><mi>i</mi></msub><mo>=</mo><msub><mi>X</mi><mi>j</mi></msub></mrow><annotation encoding="application/x-tex">X_i = X_j</annotation></semantics></math></span><span aria-hidden="true" class="katex-html"><span class="strut" style="height:0.68333em;"></span><span class="strut bottom" style="height:0.969438em;vertical-align:-0.286108em;"></span><span class="base textstyle uncramped"><span class="mord"><span class="mord mathit" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:-0.07847em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight">i</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mrel">=</span><span class="mord"><span class="mord mathit" style="margin-right:0.07847em;">X</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:-0.07847em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight" style="margin-right:0.05724em;">j</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span></span></span></span>;
  • 对称性:<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>d</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo>(</mo><msub><mi>x</mi><mi>i</mi></msub><mo separator="true">,</mo><msub><mi>x</mi><mi>j</mi></msub><mo>)</mo><mo>=</mo><mi>d</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo>(</mo><msub><mi>x</mi><mi>j</mi></msub><mo separator="true">,</mo><msub><mi>x</mi><mi>i</mi></msub><mo>)</mo></mrow><annotation encoding="application/x-tex">dist(x_i,x_j)=dist(x_j,x_i)</annotation></semantics></math></span><span aria-hidden="true" class="katex-html"><span class="strut" style="height:0.75em;"></span><span class="strut bottom" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="base textstyle uncramped"><span class="mord mathit">d</span><span class="mord mathit">i</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mopen">(</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight">i</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mpunct">,</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight" style="margin-right:0.05724em;">j</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mclose">)</span><span class="mrel">=</span><span class="mord mathit">d</span><span class="mord mathit">i</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mopen">(</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight" style="margin-right:0.05724em;">j</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mpunct">,</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight">i</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mclose">)</span></span></span></span>;
  • 直递性:<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>d</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo>(</mo><msub><mi>x</mi><mi>i</mi></msub><mo separator="true">,</mo><msub><mi>x</mi><mi>j</mi></msub><mo>)</mo><mo><</mo><mo>=</mo><mi>d</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo>(</mo><msub><mi>x</mi><mi>i</mi></msub><mo separator="true">,</mo><msub><mi>x</mi><mi>k</mi></msub><mo>)</mo><mo>+</mo><mi>d</mi><mi>i</mi><mi>s</mi><mi>t</mi><mo>(</mo><msub><mi>x</mi><mi>k</mi></msub><mo separator="true">,</mo><msub><mi>x</mi><mi>j</mi></msub><mo>)</mo></mrow><annotation encoding="application/x-tex">dist(x_i,x_j) <= dist(x_i,x_k) +dist(x_k,x_j)</annotation></semantics></math></span><span aria-hidden="true" class="katex-html"><span class="strut" style="height:0.75em;"></span><span class="strut bottom" style="height:1.036108em;vertical-align:-0.286108em;"></span><span class="base textstyle uncramped"><span class="mord mathit">d</span><span class="mord mathit">i</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mopen">(</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight">i</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mpunct">,</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight" style="margin-right:0.05724em;">j</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mclose">)</span><span class="mrel"><</span><span class="mrel">=</span><span class="mord mathit">d</span><span class="mord mathit">i</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mopen">(</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight">i</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mpunct">,</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight" style="margin-right:0.03148em;">k</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mclose">)</span><span class="mbin">+</span><span class="mord mathit">d</span><span class="mord mathit">i</span><span class="mord mathit">s</span><span class="mord mathit">t</span><span class="mopen">(</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight" style="margin-right:0.03148em;">k</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mpunct">,</span><span class="mord"><span class="mord mathit">x</span><span class="msupsub"><span class="vlist"><span style="top:0.15em;margin-right:0.05em;margin-left:0em;"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span><span class="reset-textstyle scriptstyle cramped mtight"><span class="mord mathit mtight" style="margin-right:0.05724em;">j</span></span></span><span class="baseline-fix"><span class="fontsize-ensurer reset-size5 size5"><span style="font-size:0em;">​</span></span>​</span></span></span></span><span class="mclose">)</span></span></span></span>
直递性常被直接称为“三角不等式”。

2 常见的距离公式

2.1 欧式距离(Euclidean Distance):

欧氏距离是最容易直观理解的距离度量方法,我们小学、初中和高中接触到的两个点在空间中的距离一般都是指欧氏距离。

举例:

X=[[1,1],[2,2],[3,3],[4,4]];
经计算得:
d = 1.4142    2.8284    4.2426    1.4142    2.8284    1.4142

2.2 曼哈顿距离(Manhattan Distance):

在曼哈顿街区要从一个十字路口开车到另一个十字路口,驾驶距离显然不是两点间的直线距离。这个实际驾驶距离就是“曼哈顿距离”。曼哈顿距离也称为“城市街区距离”(City Block distance)。

image-20191225113335163

举例:

X=[[1,1],[2,2],[3,3],[4,4]];
经计算得:
d =   2     4     6     2     4     2

2.3 切比雪夫距离 (Chebyshev Distance):

国际象棋中,国王可以直行、横行、斜行,所以国王走一步可以移动到相邻8个方格中的任意一个。国王从格子(x1,y1)走到格子(x2,y2)最少需要多少步?这个距离就叫切比雪夫距离。

image-20191225113241813

举例:

X=[[1,1],[2,2],[3,3],[4,4]];
经计算得:
d =   1     2     3     1     2     1

2.4 闵可夫斯基距离(Minkowski Distance):

闵氏距离不是一种距离,而是一组距离的定义,是对多个距离度量公式的概括性的表述。

两个n维变量a(x11,x12,…,x1n)与b(x21,x22,…,x2n)间的闵可夫斯基距离定义为:

image-20190225182628694

其中p是一个变参数:

  • 当p=1时,就是曼哈顿距离;
  • 当p=2时,就是欧氏距离;
  • 当p→∞时,就是切比雪夫距离。

根据p的不同,闵氏距离可以表示某一类/种的距离。

小结:

1 闵氏距离,包括曼哈顿距离、欧氏距离和切比雪夫距离,都存在明显的缺点:

e.g. 二维样本(身高[单位:cm],体重[单位:kg]),现有三个样本:a(180,50),b(190,50),c(180,60)。

a与b的闵氏距离(无论是曼哈顿距离、欧氏距离或切比雪夫距离)等于a与c的闵氏距离。但实际上身高的10cm并不能和体重的10kg划等号。

2 闵氏距离的缺点:

(1)将各个分量的量纲(scale),也就是“单位”相同的看待了;

(2)未考虑各个分量的分布(期望,方差等)可能是不同的。


【拓展】其他距离公式

3 “连续属性”和“离散属性”的距离计算

我们常将属性划分为"连续属性" (continuous attribute)和"离散属性" (categorical attribute),前者在定义域上有无穷多个可能的取值,后者在定义域上是有限个取值.

  • 若属性值之间存在序关系,则可以将其转化为连续值,例如:身高属性“高”“中等”“矮”,可转化为{1, 0.5, 0}。

    • 闵可夫斯基距离可以用于有序属性。
  • 若属性值之间不存在序关系,则通常将其转化为向量的形式,例如:性别属性“男”“女”,可转化为{(1,0),(0,1)}。

4 小结

  • 1 距离公式的基本性质:非负性、统一性、对称性、直递性【了解】
  • 2 常见距离公式

    • 2.1 欧式距离(Euclidean Distance)【知道】:

      • 通过距离平方值进行计算
    • 2.曼哈顿距离(Manhattan Distance)【知道】:

      • 通过距离的绝对值进行计算
    • 3.切比雪夫距离 (Chebyshev Distance)【知道】:

      • 维度的最大值进行计算
    • 4.闵可夫斯基距离(Minkowski Distance)【知道】:

      • 当p=1时,就是曼哈顿距离;
      • 当p=2时,就是欧氏距离;
      • 当p→∞时,就是切比雪夫距离。
  • 3 属性【知道】

    • 连续属性
    • 离散属性,

      • 存在序关系,可以将其转化为连续值
      • 不存在序关系,通常将其转化为向量的形式

程序员一诺python
16 声望16 粉丝

python技术发烧友 资料收集狂