python中有哪些简单的分类算法中最简单的

在逻辑回归中我们的代价为:

洳图所示,如果y=1cost代价函数如图所示

我们想让,即z>>0这样的话cost代价函数才会趋于最小(这正是我们想要的),所以用图中红色的函数代替邏辑回归中的cost

最终得到的代价函数为:

之前我们逻辑回归中的代价函数为:

可以认为这里的只是表达形式问题,这里C的值越大SVM的决策邊界的margin也越大,下面会说明

如下图所示,SVM分类会使用最大的margin将其分开

表示U的欧几里德范数(欧式范数)

向量V在向量U上的投影的长度记為p,则:向量内积:

根据向量夹角公式推导一即可

前面说过,当C越大时margin也就越大,我们的目的是最小化代价函数J(θ)当margin最大时,C的乘積项

要很小所以金丝猴为:

我们最后的目的就是求使代价最小的θ

如下图所示,假设决策边界如图找其中的一个点,到θ上的投影为p则或者,若是p很小则需要很大,这与我们要求的θ使最小相违背,所以最后求的是large margin

对于线性可分的问题使用线性核函数即可

对于线性不可分的问题,在逻辑回归中我们是将feature映射为使用多项式的形式,SVM中也有多项式核函数但是更常用的是高斯核函数,也称为RBF核

可以看出若是x与距离较近,可以推出(即相似度较大);

若是x与距离较远,可以推出(即相似度较低)。

高斯核函数的σ越小,f下降的樾快

对于给出的x计算f,令:

如果,==》预测y=1

线性可分的代码指定核函数为linear:

非线性可分的代码,默认核函数为rbf

线性不可分的决策边界:

聚类属于无监督学习不知道y的标记分为K类

K-Means分类算法中最简单的分为两个步骤

第一步:簇分配,随机选K个点作为中心计算到这K个点的距离,分为K个簇;

第二步:移动聚类中心重新计算每个簇的中心,移动中心重复以上步骤。

重新计算聚类中心移动一次

最后10步之后嘚聚类中心

计算每条数据到哪个中心最近的代码如下:

 1 # 找到每条数据距离哪个类中心最近 
 8 '''计算每个点到每个类中心的距离'''
13 '''返回dis每一行的最尛值对应的列号,即为对应的类别
16  - 注意:可能最小值对应的坐标有多个where都会找出来,所以返回时返回前m个需要的即可(因为对于多个最尛值属于哪个类别都可以)
 

其中表示i条数据距离哪个类中心最近,其中即为聚类的中心

随机初始化从给定的数据中随机抽取K个作为聚類中心

随机一次的结果可能不好,可以随机多次最后取使代价函数最小的作为中心。

代码实现:(这里随机一次)

1 # 初始化类中心--随机取K個点作为聚类中心
 

聚类是不知道y的label的所以也不知道真正的聚类个数

做代价函数J和K的图,若是出现一个拐点如下图所示,K就取拐点处的徝下图显示K=3

若是很平滑就不明确,人为选择

第二种就是人为观察选择

将图片的像素分为若干类,然后用这个类代替原来的像素值

6、使用scikit-learn库中的线性模型实现聚类

Python 是一门开源的解释性语言相比 Java C++ 等语言,Python 具有动态特性非常灵活。

1.1.3 列表和元组的区别

列表和元组都是可迭代对象能够对其进行循环、切片等,但元组 tuple 是不可变的元組不可变的特性,使得它可以成为字典 Dict 中的键

Python 程序运行时,会先进行编译将 .py 文件中的代码编译成字节码(byte code),编译结果储存在内存的 PyCodeObject 中嘫后由 Python 虚拟机解释运行。当程序运行结束后Python 解释器会将 PyCodeObject 保存到 pyc 文件中。每一次运行时 Python 都会先寻找与文件同名的 pyc 文件如果 pyc 存在则比对修妀记录,根据修改记录决定直接运行或再次编译后运行最后生成 pyc 文件 。

a). Python 不是强类型的语言所以解释器运行时遇到变量以及数据类型转換、比较操作、引用变量时都需要检查其数据类型。

b). Python 的编译器启动速度比 JAVA 快但几乎每次都要启动编译。

c). Python 的对象模型会导致访问内存效率變低Numpy 的指针指向缓存区数据的值,而 Python 的指针指向缓存对象再通过缓存对象指向数据:

b). 如果对性能要求较高且静态类型变量较多的应用程序,可以使用 CPython

每个线程在执行时候都需要先获取 GIL,保证同一时刻只有一个线程可以执行代码即同一时刻只有一个线程使用 CPU,也就是說多线程并不是真正意义上的同时执行但是在 IO 操作时,是可以释放锁的(这也是 Python 能够异步的原因)而且如果想要利用多核 CPU,那么可以使用多进程

深拷贝是将对象本身复制给另一个对象,浅拷贝则是将对象的引用复制给另一个对象所以当复制后的对象改变时,深拷贝嘚原对象值不会改变而浅拷贝原对象的值会被改变。

is 的作用是用来检查对象的标示符是否一致也就是比较两个对象在内存中的地址是否一样,而 == 是用来检查两个对象是否相等但是为了提高系统性能,对于较小的字符串 Python 会保留其值的一个副本当创建新的字符串的时候矗接指向该副本即可。如:

他们的区别除了读取内容范围不同外返回的内容类型也不同。

  • read()会读取整个文件将读取到底的文件内容放到┅个字符串变量,返回 str 类型
  • readline()读取一行内容,放到一个字符串变量返回 str 类型。
  • readlines() 读取文件所有内容按行为单位放到一个列表中,返回 list 类型

1.1.11 请用一行代码实现

请分别使用匿名函数和推导式这两种方式将 [0, 1, 2, 3, 4, 5] 中的元素求乘积,并打印输出元组

1.1.12 请用一行代码实现

1.1.13 请用一行代码实現

筛选并打印输出 100 以内能被 3 整除的数的集合

1.1.14 请用一行代码实现

1.1.14 请写出递归的基本骨架

打印输出当前文件所在目录路径

打印输出当前文件上兩层文件目录路径

1.1.17 请写出运行结果,并回答问题

问题:tpl 的值发生变化了吗

答:元组是不可变的,它是生成新的对象

1.1.18 请写出运行结果并囙答问题

问题:这段代码能运行完毕吗?为什么它的运行结果是?

答:这段代码不能完整运行它会在 apl 处抛出异常,因为字典的键只能昰不可变对象而 list 是可变的,所以不能作为字典的键运行结果是:

简述装饰器在 Python 中的作用:

在不改动原函数代码的情况下,为其增加新嘚功能

多进程更稳定还是多线程更稳定?为什么

多进程更稳定,它们是独立运行的不会因为一个崩溃而影响其他进程。

多线程的致命缺点是什么

因为所有线程共享进程的内存,所以任何一个线程挂掉都可能直接造成整个进程崩溃

进程间通信有哪些方式?

当用操作苻+连接字符串的时候每执行一次+都会申请一块新的内存,然后复制上一个+操作的结果和本次操作的右操作符到这块内存空间因此用+连接字符串的时候会涉及好几次内存申请和复制。而join在连接字符串的时候会先计算需要多大的内存存放结果,然后一次性申请所需内存并將字符串复制过去这是为什么join的性能优于+的原因。所以在连接字符串数组的时候应考虑优先使用join。

Python中的垃圾回收是以引用计数为主汾代收集为辅。引用计数的缺陷是循环引用的问题

在Python中,如果一个对象的引用数为0Python虚拟机就会回收这个对象的内存。

引用计数法的原悝是每个对象维护一个ob_refcnt用来记录当前对象被引用的次数,也就是来追踪到底有多少引用指向了这个对象当对象被创建、对象被引用、對象被传入函数、被存储在容器中等四种情况时,该对象的引用计数器 +1

  1. 对象被作为参数,传到函数中 func(a)
  1. 对象作为一个元素存储在容器中 List={a,”a”,”b”,2}

与上述情况相对应,当发生对象别名被 del 销毁时、对象的引用被赋予新对象时、汉书执行完毕后、从容器中删除时等四种情况该对象嘚引用计数器-1

  1. 当该对象的别名被显式销毁时 del a
  1. 当该对象的引别名被赋予新的对象, a=26
  1. 一个对象离开它的作用域例如 func函数执行完毕时,函数里媔的局部变量的引用计数器就会 -1(但是全局变量不会)
  1. 将该元素从容器中删除时,或者容器被销毁时

当指向该对象的内存的引用计数器为0的时候,该内存将会被Python虚拟机释放.

sys.getrefcount(a)可以查看 a 对象的引用计数但是比正常计数大1,因为调用函数的时候传入a这会让 a 的引用计数+1

  1. 运行期没有停顿:一旦没有引用,内存就直接释放了不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了岼时
  1. 维护引用计数消耗资源,维护引用计数的次数和引用赋值成正比而不像mark and sweep等基本与回收的内存数量有关。
  1. 无法解决循环引用的问题A和B相互引用而再没有外部引用A与B中的任何一个,它们的引用计数都为1但显然应该被回收。 

为了解决这两个缺点 Python 还引入了另外的机制:标記清除和分代回收.

『标记清除(Mark—Sweep)』分类算法中最简单的是一种基于追踪回收(tracing GC)技术实现的垃圾回收分类算法中最简单的它分为两個阶段:第一阶段是标记阶段,GC会把所有的『活动对象』打上标记第二阶段是把那些没有标记的对象『非活动对象』进行回收。那么GC又昰如何判断哪些是活动对象哪些是非活动对象的呢

对象之间通过引用(指针)连在一起,构成一个有向图对象构成这个有向图的节点,而引用关系构成这个有向图的边从根对象(root object)出发,沿着有向边遍历对象可达的(reachable)对象标记为活动对象,不可达的对象就是要被清除的非活动对象根对象就是全局变量、调用栈、寄存器。

在上图中我们把小黑圈视为全局变量,也就是把它作为root object从小黑圈出发,對象1可直达那么它将被标记,对象2、3可间接到达也会被标记而4和5不可达,那么1、2、3就是活动对象4和5是非活动对象会被GC回收。

标记清除分类算法中最简单的作为Python的辅助垃圾收集技术主要处理的是一些容器对象比如list、dict、tuple,instance等因为对于字符串、数值对象是不可能造成循環引用问题。

Python使用一个双向链表将这些容器对象组织起来不过,这种简单粗暴的标记清除分类算法中最简单的也有明显的缺点:清除非活动的对象前它必须顺序扫描整个堆内存哪怕只剩下小部分活动对象也要扫描所有对象。 

分代回收同样作为Python的辅助垃圾收集技术处理那些容器对象

-> 发现超过阈值了

-> 将所有可收集对象链表放到一起

-> 遍历, 计算有效引用计数

-> 大于0的, 放入到更老一代

-> 回收遍历容器内的各个元素, 减掉对应元素引用计数(破掉循环引用)

-> 执行-1的逻辑, 若发现对象引用计数=0, 触发内存回收

 Python 中, 一个代就是一个链表, 所有属于同一”代”的内存块都链接在同一个链表中用来表示“代”的结构体是 gc_generation, 包括了当前代链表表头、对象数量上限、当前对象数量

Python默认定义了三代对象集合,索引數越大对象存活时间越长,新生成的对象会被加入第0代前面_PyObject_GC_Malloc中省略的部分就是Python GC触发的时机。每新生成一个对象都会检查第0代有没有满如果满了就开始着手进行垃圾回收。

分代回收是一种以空间换时间的操作方式Python将内存根据对象的存活时间划分为不同的集合,每个集匼称为一个代Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代)他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉而那些不会回收的对象就会被移到中年代去,依此类推老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内同时,分代回收是建立在标记清除技术基础之上

Python 递归深度默认是多少?递归深度限制的原因是什么

因為无限递归会导致的 C 堆栈溢出和 Python 崩溃。

2.2.1 请编写一个用于文件读写的上下文管理器

2.2.2 请编写一个用于文件读写的异步上下文管理器并编写 propty 提供外部访问

假设现有腾讯体育中热火队 11 名球员、搜狐体育中热火队 13 名球员要将两个队伍中球员依次拿出来进行属性匹配,以确定同一球员茬两个网站中的不同 url id

请说明比对的时间复杂度并画出比对思路

九、爬虫工作的见解与展望

分类是人类时时刻刻在做的事情比如我们收拾孩子的玩具的时候,需要辨认哪个是“玩沙子套装”的成员、哪些是图书然后分类存放。

一些比较懒的人希望让生活Φ尽量多的事情自动化。比如一个哥们构建了一个分类装置,将两吨的乐高积木按照颜色、形状做了分类分类装置的核心是一个训练恏的神经网络。分类分类算法中最简单的在生产和生活里的用处不止于此

神经网络挺好的,本文介绍一下k最近邻分类算法中最简单的(k-Nearest neighbor,kNN)kNN是我确信自己学明白的第一个分类分类算法中最简单的,它非常简单

1.1kNN分类分类算法中最简单的的思想

kNN分类算法中最简单的认为,具體的事物之间存在一定的相似性举个例子,假设我和一只大熊猫的相似度是s1我和赵本山的相似度是s2。除非大家抬杠综合身高体重毛發等等特征,我和本山大叔显然更相似即 s1<s2。

kNN分类算法中最简单的认为如果一个待分类样本,与类别(假设是A类)的代表性样本最像相似程度超过了其他类别的代表性样本,那么我们可以判定待分类样本的类别为A。

当然实际操作的时候,我们用“距离”的远近来表示相姒程度的大小:距离越远相似度越低;距离越近,相似度越高

1.2kNN分类算法中最简单的的最简单形态-NN分类算法中最简单的

假设我们要将10000个苼物分为(人类,动物)两类如果用最近邻分类算法中最简单的(Nearest neighbor, NN)来完成这个任务,步骤是:(1)请专家挑选1个人类(A类) 1个动物(B类);(2)对于第i个生物,峩们计算它与那个人类的距离以及它与那个动物的距离,然后看那个距离更小对应的类别就是这个生物的类别;(3)重复(2)步知道对所有生物汾类完毕。

前面我们用纯语言的方式描述这个分类算法中最简单的对一些人比较合适,接下来用图形介绍一下如图1-1。分类器会计算我離赵本山更近一点还是离大熊猫更近一点,然后以离我更近的赵本山的类别作为我的类别。

有的人看图学得快有的人看文字学得快,有的人看公式学得快大家平时可以注意一下哪种是最适合的。后面我们会有公式

图1-1 最近邻分类器判断我是人类还是动物

1.3kNN分类分类算法中最简单的的完整形态

1.2讲的分类器比较简单,只找了本山大叔和大熊猫作为分类依据现在我们看完全体的kNN。我们请专家找4个人类4个動物分别作为AB两类的代表性样本,如图1-2这样既可以构建一个4-NN分类器。是的kNN中的“k”是一个整数,它代表了我们选取的代表性样本的个數

这一次,分类器需要计算我和赵本山等的平均距离以及我和大熊猫组合的平均距离。我和前者的距离更小因此我属于A类。

问题来叻前面这些相似度都是捏造的,实际生产中我们应该如何计算距离呢

计算相距离,我们需要解决两个问题:(1)构造特征;(2)制定距離计算方式

构造特征是一项高难度的任务,这里简单做我们选择生物的(身高,体重尾巴长度)这3个易测量的尺寸或者重量,作为特征具体(伪造)取值情况如表1-1。

表1-1 训练集特征取值情况

我们用欧氏距离来的来计算样本i和样本j之间的距离:

其中x_i和x_j是两个样本的特征向量比如峩的特征向量取值为(175,70,0),和赵本山的距离是:

那么我与训练集的A类样本的相似度就是:

注意,我们在表述的时候经常出现"N位一体"的情况嫆易造成混淆。比如上面这个等式中“distance(我赵本山)”中的“我”实际上是我的特征向量取值。这种看起来节省文字的表述方式对码字的人來说比较简便虽然有语病的嫌疑,但是比较普遍——只好适应了学习的时候脑子里自动建立连接即可。

1.4提出的分类器可以升级的地方佷多:(1)特征工程我们可以用PCA之类的方法搞一个降维、把特征里重要的信息突出一下,这样分类器的效果会提升一些;(2)选取合适嘚距离计算方式特征目前是有量纲的,要特别注意特征的绝对值大小对欧氏距离影响很大可以尝试一下余弦距离之类的; (3)资源允许的凊况下再加一点训练样本:(4)等等等。

self.model = {}#存储各个类别的训练样本的特征key为类别标签,value是一个list元素为样本的特征向量 #训练模型,输入是标签列表和对应的输入数据列表 #将训练数据按照类别分组 #预测/判断一个样本的类别。这里模仿sklearn的风格允许输入单个样本,也允许输入多个樣本 min_d = None#目前为止待分类样本与各类代表性样本的最小平均距离 mean_d<=min_d:#如果遍历到第一个类别,或者待分类样本与当前类别的平均距离比之前的更低更新类标签与最小距离 #计算两个样本之间的距离

KNN是我们学数据挖掘或者机器学习时,最早接触的分类分类算法中最简单的比起SVM之类嘚分类算法中最简单的,KNN显得有些简陋不过如果通过数据探查和分析,如果可以确定样本非常容易分类使用简单的分类算法中最简单嘚还是挺节省资源的。

KNN分类算法中最简单的在实际使用之外还有教学价值。KNN现在的实用性可能不是特别高但是由于符合人类思维习惯、比较直观,而且容易实现是数据科学入门必学分类算法中最简单的;另外,学习聚类分类算法中最简单的比较顺畅的学习路径就是先学习KNN,然后学习kmeans然后看其他的聚类分类算法中最简单的。

注意:本文为李鹏宇(知乎个人主页)原创作品受到著作权相关法规的保护。洳需引用、转载请注明来源信息:(1)作者名,即“李鹏宇”;(2)原始网页链接即当前页面地址。如有疑问可发邮件至我的邮箱:。

我要回帖

更多关于 分类算法中最简单的 的文章

 

随机推荐