在中,我们讲到了集成学习按照个体学习器之间是否存在依赖关系可以分为两类:
前者的代表算法就是提升(boosting)系列算法。在boosting系列算法中, Adaboost是最著名的算法之一。Adaboost既可以用作分类,也可以用作回归。本文就对Adaboost算法做一个总结。
AdaBoost是典型的Boosting算法,属于Boosting家族的一员。在说AdaBoost之前,先说说Boosting提升算法。Boosting算法是将“弱学习算法“提升为“强学习算法”的过程,主要思想是“三个臭皮匠顶个诸葛亮”。一般来说,找到弱学习算法要相对容易一些,然后通过反复学习得到一系列弱分类器,组合这些弱分类器得到一个强分类器。Boosting算法要涉及到两个部分,加法模型和前向分步算法。加法模型就是说强分类器由一系列弱分类器线性相加而成。一般组合形式如下:$$f(x;P)=\sum_{k=1}^Kβ_kh(x;\gamma_k)$$
其中,$h(x;\gamma_k)$ 就是一个个的弱分类器,$\gamma_k$是弱分类器学习到的最优参数,$β_k$ 就是弱学习在强分类器中所占比重,$P$ 是所有$\gamma_k$和$\beta_k$ 的组合。这些弱分类器线性相加组成强分类器。
前向分步就是说在训练过程中,下一轮迭代产生的分类器是在上一轮的基础上训练得来的。也就是可以写成这样的形式:
由于采用的损失函数不同,Boosting算法也因此有了不同的类型,AdaBoost就是损失函数为指数损失的Boosting算法。
在前面一节,我们已经讲到了boosting算法系列的基本思想,如下图:
从图中可以看出,Boosting算法的工作机制是首先从训练集用初始权重D(1)训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。然后基于调整权重后的训练集来训练弱学习器.php等技术开发的Web应用产品中. 硕正套件部署于服务器,支持 ...
为什么需要线程同步? 同步就是协同步调,按预定的先后次序进行运行.如:你说完,我再说而并非一起动作.“同”字应是指协同.协助.互相配合. 如进程.线程同步,可理解为进程或线程A和B一块配合,A执行到一 ...
Java是面向对象的编程语言,不同于C语言是面向过程的。对于面向对象和面向过程的区别,举一个简单的例子说明一下(我们以洗衣机洗衣服为例):
面向过程:面向过程的编程方式,程序会将要完成的某一个任务拆解成一系列的小步骤 (函数),如:
面向对象:面向对象的编程方式,程序会将要完成的洗衣机洗衣服的任务拆分成如下两个对象:
Person
):Person
在洗衣机洗衣服这个程序任务中有三个作用,分别是打开洗衣机
、放入要洗的衣服
、放入洗衣粉。
Machine
):Machine
在洗衣机洗衣服这个程序任务中有两个作用,分别是清洗
、烘干
。
从上面这个例子能看出,面向过程的编程方式比较直接且高效,而面向对象的编程方式更易复用、扩展和维护!
继承:承是Java中面向对象最显著的一个特征,继承是从已有的类中派生出新的类,新的类可以吸收已有的属性、行为,并扩展新的能力。Java中不支持多继承,但是接口可以支持多实现。
封装:将同一类事物的特征和功能包装在一起,只对外暴露需要调用的接口。封装也称为信息的隐藏,在Java中接口是体现封装最常用的方法,在接口中我们没有任何功能的实现(具体实现都交给实现类),只是定义了一系列抽象的方法声明用于外部调用。
多态:封装和继承都是为多态来服务的,多态是指同一个行为具有多个不同的表现形式。在Java中方法的重载和重写是实现多态的2种方式。
重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载。方法重载体现了编译时的多态性。
什么是编译形语言,什么又是解释形语言?
那么为什么说Java 是编译型语言呢?
第一个观点认为 Java 是编译型语言,因为Java程序想要运行,那么第一步就是要使用Javac进行编译(将Java源文件编译成.class
二进制文件)。没有经过编译的.java
文件,是没办法运行的!
那么为什么又说Java 是解释型语言呢?
那么第二个观点则是认为Java是解释型语言,Java经过编译,Javac 将.java
源文件编译成.class
二进制文件之后,仍然需要借助 JVM 的解释执行。
综合上面两个观点来看,Java似乎既有编译型语言的特点,又有解释型语言的特点,也没有看到哪本权威的书籍上认定Java就是哪一种类型的语言。
8种基本数据类型和取值范围:
0 |
0 |
0 |
0 |
注意:对于boolean
值,在Java规范中并没有给出其储存大小,在《Java虚拟机规范》中给出了4个字节,和boolean
数组1个字节的定义,具体还要看虚拟机实现是否按照规范来,所以1个字节、4个字节都是有可能的。除了void之外,其他8种基本数据类型被称为八大基本数据类型。
图中从左向右的转换都是隐式转换,无需再代码中进行强制转换。从右向左均要进行强制类型转换,才能通过编译。强制转换会丢失精度。
(二) 成员属性方面:
public static final
修饰,这个可以省略不写;
(四) 构造函数方面:
JDK1.8以前是只能有抽象方法。
抽象类中除了静态方法和抽象方法外还可以有普通方法。
是值传递。java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。
java中只有值传递,基本类型传递的是值的副本,引用类型传递的是引用的副本
直接看一张图就可以理解他们的区别了:
重载:方法重载发生在同一个类中,重载的方法之间方法名必须相同,参数列表不同(参数的类型、参数的个数),方法的返回值和访问修饰符可以不同,发生在编译时期(方法重载实现了编译时多态)。
重写:方法重写发生在子父类中,子类重写父类的方法,方法名称必须相同,参数列表也必须相同,方法的返回值小于等于父类方法的返回值,访问修饰符方位大于等于父类方法(如果父类方法修饰符为private
,则子类就无法重写了)。
List
:有序、可重复集合。按照对象插入的顺寻保存数据,允许多个Null
元素对象,可以使用iterator
迭代器遍历,也可以使用get(int index)
方法获取指定下标元素。
Set
:无序、不可重复集合只允许有一个Null
元素对象,取元素时,只能使用iterator
迭代器逐一遍历。
Map
: key-value 键值对形式的集合,添加或获取元素时,需要通过key来检索到value。
equals()
只是判断对象属性是否相同,hashCode()
要判断二者地址是否相同。java中如果要判断两个对象是否相等,需要同时满足地址 + 属性
都相同!
equals()
比较返回true),
那么它们的 hashCode
值一定要相同;
hashCode
相同,它们并不一定相同;
执行下面的程序看看效果:
如果重写了 equals()
而未重写 hashcode()
方法,可能就会出现两个没有关系的对象 equals 相同(因为equals都是根据对象的特征进行重写的),但 hashcode 不相同的情况。因为此时
根据 hashcode 的规则,两个对象相等其 hash 值一定要相等,矛盾就这样产生了。上面我们已经解释了为什么要使用 hashcode
算法,所以即使字面量相等,但是产生两个不同的 hashCode 值显然不是我们想要的结果。
两位同学是同一个人吗?true
从 Student 类重写后的 hashcode() 方法中可以看出,重写后返回的新的 hash 值与 Student 的两个属性是有关,这样就确保了对象和对象地址之间的关联性。
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
inspect模块也被称为 检查现场对象。这里的重点在于“现场”二字,也就是当前运行的状态。
inspect模块提供了一些函数来了解现场对象,包括 模块、类、实例、函数和方法。
inspect函数主要用于以下四个方面
本文章会先带大家大概了解一下inspect模块有哪些功能,以及有哪些功能函数,然后再结合实例,解释每个方法他们的使用场景以及使用方法。
第二个参数通常可以根据需要调用如下16个方法;
返回值为object的所有成员,以(name,value)对组成的列表
name:模块名(不包括其所在的package)
inspect.getmembers()函数用于发现对象的成员属性。返回的成员类型取决于我们所传入的对象类型。传入的参数可以是 模块、类、实例、函数、方法。
object可以是 模块、类、实例、函数、方法;
predict表示的是谓语,可以是isclass(),ismodule()等等,用于筛选,看了后面例子就懂了。
用于获取对象的成员属性
现在准备了两个py文件,example_inspect.py文件中存放了一些类和方法的定义,作为模块;do_inspect.py文件会将上个py文件当作模块导入;来看这个模块里面有哪些成员。如下
上面的代码有3个注意点:
1、我们将example_inspect.py作为模块传入getmembers()方法,可以打印出这个模块中所有的成员,并以元组列表形式放回。
2、注意到我在遍历 getmembers()方法时,使用了 if name.startwith("--"),这是为什么呢?因为模块有一些私有属性作为导入实现的一部分,还会包含一组__builtins__。这两个东西的列表非常长,我们一般也都不关心。所以使用if将他们过滤掉。
3、我们还可以将do_inspect.py写法改变一下,如下,利用getmembers的谓语参数,可以选择得到自己想要的成员变量
所以当传入的参数为module时,不能打印出 类的方法。但是可以打印出 模块级别的函数。(与后面参数为 类 时做对比)
会打印出一堆结果,这里我只粘贴上了一部分,以双下划线开始的变量基本都是继承object得来的和一些自带的变量。但是注意到,打印出了 方法:get_name()和__init__() do_nothing() test(),如果我们给类A添加了类变量,同样也会打印出来。
当然我们可以使用 谓语 来筛选。
当然,如果类里面定义了类方法,ismethod会打印出这个类方法,因为类也是对象,而类方法就是与类绑定的方法
在B继承于A情况下,B拥有了A的方法,因此也被打印出来。
可以看出,类方法和实例方法都被打印出来,而静态方法被忽略掉
这两个函数在我们编程中用到的很少。这里也就不做介绍了。后面用到的话,直接去官方文档看就可以了。
getsourcelines()的返回值是一个tuple,其中包含一个字符串列表,和文件中源代码出现的起始行号,如下
3.1 (补充知识)函数签名是什么?
函数签名对象,表示调用函数的方式,即定义了函数的输入和输出
一个函数由这么bai几部分组成,函数名、参数个数、参数类型、返回值。函数签名就是指 参数个数、参数类型。
那么为什么会有参数签名这么个东西呢?
答:函数在重载时,利用函数签名的不同(即参数个数与类型的不同)来区别调用者到底调用的是那个方法。就如同下面两个方法,语言正是通过他们的函数签名不同,来区别同函数名但是不同参数的函数。
3.2(补充知识)python函数的参数分类
那么,我们把这些参数给扣出来又有什么用呢?
我们可以先为这些参数赋值,然后再去调用我们的函数。就实现了:先给参数赋值,然后再去和函数发生关联、调用。
使用函数签名的bind的方法,检查函数参数是否匹配签名。
继续延续 inspect_example.py的例子,通过函数签名的bind方法,接受函数参数。如果匹配,返回参数BoundArguments实例,如果不匹配,则抛出TypeError,并给出详细的异常信息。
通过BoundArguments实例的属性,可以获取函数签名、参数的值等内容。
并且,bind()函数必须指定 必传参数,默认参数不会计入到 BoundArguments中
也许你对上面三句话不太懂,那么好好看下面的代码例子,你就懂了。
这里只介绍getmro()函数,它接受的参数为 类,然后返回值是一个 类的tuple,它会解析出传入类的所有基类,并按照mro的顺序排列。(不从mro的,自行百度吧,比较简单的概念就不说了)
为了讲清楚这里,需要补充一些知识:
5.1.1、栈帧是什么,以及程序调用与栈帧
看完了关于栈帧的文章,相信大家已经知道栈帧是什么,以及函数调用时是如何将信息存入栈帧的。
我们经常说的 某一帧 指的就是一个函数存储在栈中的所有信息 就是一帧, 千万不要以为某一帧就是说的某一条数据,帧是一个块的概念。
那么frame对象又是什么呢?
Frame对象表示执行帧,表示程序运行时函数调用栈中的某一帧。
想要获得某个函数相关的栈帧,则必须在调用这个函数且这个函数尚未返回时获取。可以使用sys模块的_getframe()函数、或inspect模块的currentframe()函数获取当前栈帧。
而frame包含了一些属性,其实这些属性对应的就是我们在栈帧里存储的数据,如下
前一个堆栈帧(朝向调用者),如果这是底部堆栈帧则为None |
在这个框架中执行的Code对象 |
用于查找局部变量的字典 |
表示该函数是否在限制执行模式下执行的标志 |
给出精确的指令(这是代码对象的字节码字符串的索引) |
当前代码在文件中的哪一行 |
上面这些参数,大家可以通过ID E调试,看到他们的组成。还有很多参数我没有介绍。我这里只给出一个例子,大家可以自己去调试。
使用stack()函数,还可以访问到当前帧到第一个调用者的所有栈帧。这个例子与上面的例子相似。只不过它会一直等待,直到递归结束,再打印栈信息。
其实stack()获取的就是frame的列表,是一个按照调用顺序包含了所有栈帧的列表。
那么,它有什么用处呢?
我用它排插过错误,通过定位栈,来定位错误的来源。其他的场景还没有用过。如果后面有的话,再补充。
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。