Python语言常用面试题

发布时间:2023-09-22 13:48
最后更新:2023-09-22 13:48
所属分类:
面试题集锦

这篇文章中所列出的面试题主要提供 Python 相关职位面试使用。其中主要包括 Python 语言的基础知识、常见 Web 框架的基本应用、大数据基础知识和一部分神经网络的基础知识。

专题系列文章:

  1. 关于面试题集锦的使用
  2. IT系列职位通用常用面试题
  3. 基本IT知识常用面试题
  4. Go语言常用面试题
  5. Java语言常用面试题
  6. Python语言常用面试题
  7. 数据库知识常用面试题
  8. 前端技术栈常用面试题

Python 相关知识

现在有一个大小约 10G 的文件需要处理,但是内存只有 4G,要使用什么办法处理?

使用生成器对文件内容进行迭代,生成器可以控制每次读入内存的内容大小,并且可以记录已经读取到的位置。

有一个字符串 “Hello world”,如何获取其反转内容的字符串。

"Hello world"[::-1]

给定两个列表,怎么找出他们相同的元素和不同的元素?

将列表转换成 Set ,利用集合的交集和差集获取。

如何快速删除列表里面的重复元素?

list2 = list(set(list1))

如何删除列表里的元素?

  • 复制一个新列表,在新列表中遍历获取索引,在旧列表中操作。
  • 使用列表生成器进行过滤,或者使用过滤函数搭配 Lambda 表达式进行过滤。
  • 倒序删除,保证需要被删除的索引不变。

Python 中变量的查找顺序是什么?

Python 中变量的查找是按照 LEGB 的顺序进行的,LEGB 分别为:

  1. Local:函数内部作用域。
  2. Enclosing:函数内部与内嵌函数之间。
  3. Global:全局作用域。
  4. Build-in:内置作用域。

Python 中类方法、类实例方法、静态方法有何区别?

类方法: 是类对象的方法,在定义时需要在上方使用 @classmethod 进行装饰,形参为 cls,表示类对象,类对象和实例对象都可调用。

类实例方法: 是类实例化对象的方法,只有实例对象可以调用,形参为 self,指代对象本身。

静态方法: 是一个任意函数,在其上方使用 @staticmethod 进行装饰,可以用对象直接调用,静态方法实际上跟该类没有太大关系。

【精通级别】Python 中有哪些内存管理机制?常用有哪些调优手段?

内存管理机制有:引用计数、垃圾回收(引用计数、标记清除)、内存池。

常用调优手段有:

  1. 手动垃圾回收。
  2. 调高垃圾回收阈值。
  3. 避免循环引用。

【精通级别】内存泄露是什么?如何避免?

内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。

__del__() 函数的对象间的循环引用是导致内存泄露的主凶。不使用一个对象时使用:del object 来删除一个对象的引用计数就可以有效防止内存泄露问题。可以通过 Python 扩展模块 gc 来查看不能回收的对象的详细信息。还可以通过 sys.getrefcount(obj) 来获取对象的引用计数,并根据返回值是否为 0 来判断是否内存泄露。

Python 中哪些是可变对象,哪些是不可变对象

不可变对象,该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。

可变对象,该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上其所指的值直接发生改变,并没有发生复制行为,也没有开辟出新的地址,通俗点说就是原地改变。

Pyhton 中,数值类型( intfloat ),字符串 str、元祖 tuple 都是不可变类型。而列表 list、字典 dict、集合 set 是可变类型。

在对象中怎么实现只读属性?

将字段私有化,通过公有方法或者属性提供一个读取数据的接口,但不提供写入的接口。

Python 中常用的有几种锁?

互斥锁,可重入锁,死锁。

什么是 Python 自省?

自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型。简单一句话就是运行时能够获得对象的类型。比如 type()dir()getattr()hasattr()isinstance()

Python 中单下划线和双下划线有什么含义?

单下划线表示 protected,可以在子类中访问。双下划线表示 private,只可以在本类中访问。

Python中如何实现 AOP(面向切面编程)?

装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决 AOP 这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。装饰器的作用就是为已经存在的对象添加额外的功能。

“猴子补丁”(monkey patching)指的是什么?

“猴子补丁”是指在函数或对象已经定义之后,再去改变它们的行为。会破坏代码的可维护性,违反 KISS 原则。

什么是 PEP ?

PEP 的全称是 Python Enhancement Proposals,即 Python 增强建议书。每一个 PEP 是一份为 Python 社区提供各种增强功能的技术规范,也是提交新特性,精确化技术文档的提案。

PEP 即是新特性提案,也是 Python 中标准化的内容,其中规定了 Python 代码与特性应该遵循的规范和协议。

什么是命名元组?

命名元组是元组的子类,在一定程度上可以替代类来使用。命名元组适合用来存储数据,所以适合在仅保存数据而不内置其他方法的情况下使用,类似于 Java 中的 POJO(Plain Ordinary Java Object,简单 Java 对象即普通的 Java Bean)。命名元组既可以通过 namedTuple.name 来访问元组,还可以通过 namedTuple[offset] 来访问元素。

命名元组不是 Python 内置自动支持的类型,使用之前需要使用 from collections import namedtuple 来加载命名元组类型。命名元组的使用与元组不同,它不是直接定义的元组类型数据,而是需要先定义一个带有元素命名内容的数据结构,之后再进行数据的初始化。这个数据结构的定义需要两个参数:命名元组的名称和由多个域名组成的字符串,各个域名之间使用空格隔开。

简单描述一下迭代器的使用

迭代是 Python 中最强大的功能之一,是快速科学访问集合元素的方式之一。迭代器是一个可以记录遍历位置的对象,在迭代器进行迭代时,会从集合的第一个元素开始,直到所有元素都访问结束,并且只能前进不能后退。

迭代器使用 iter(seq) 创建,使用 next(it) 进行迭代操作。可以用于创建迭代器的数据类型有列表、元组、集合和字符串。如前面所述的推导式语法,创建一个迭代器最快的方法就是使用元组推导式。

使用 next(it) 可以对生成的迭代器进行取值,并将其向下步进一位。此外,迭代器还可以使用 for 语句进行遍历。

在定义一个函数时如何捕获命名参数和不定长参数?

不定长参数使用 * 在其前方进行标记,所有未命名的变量参数都会形成一个元组传入不定长形参中。

使用 ** 在不定长参数前进行标记,则会将所有未显式定义的命名参数转化为字典。

如何定义一个生成器?

如果一个函数不使用 return 返回值,而使用 yield 返回值的函数称为生成器。与 return 不同的是,yield 用于不断的返回值,也就是说是用于迭代操作。生成器实际上就是一个迭代器。

生成器在运行过程中,遇到 yield 时就会暂停运行并保存当前的运行信息,并返回 yield 的值;当执行 next() 时,生成器会从保存的位置继续运行,并抛出下一个值。所以调用生成器返回的是一个迭代器对象。如果生成器在运行过程中遇到了 return 则会直接抛出 StopIteration 终止迭代。

如果函数需要返回一个容量很大的列表,并且其中的内容是动态计算得到的,那么使用生成器会更加经济、快速。

如何定义一个修饰器?

修饰器的定义有两种方式:函数定义方式和类定义方式。修饰器实际上就是一个函数,修饰器在模块加载的时候就会生成一个被修饰的新函数。

所以根据修饰器函数的这个特性,定义修饰器的函数实际上是返回了一个内部定义的函数。这个修饰器定义函数接受一个函数作为参数,这个参数就是被修饰的函数。在修饰器定义内部函数里,可以使用修饰器函数参数来调用执行被修饰的函数。一般来说修饰器会抹除被修饰函数的元信息,如果需要保留被修饰函数的元信息,可以使用 @functools.wraps(fn) 来修饰修饰器定义函数定义的内部函数。

因为修饰器的定义实际上就是一个函数的本质特点,那么就可以使用类和魔术方法来实现使用类定义修饰器的效果。这主要依靠实现 __call__(self, fn) 魔术方法。__call__ 魔术方法内的操作和定义就与使用函数方式定义修饰器的方法和规则就是一样的了。

什么叫“鸭子类型”?

在 Python 中,如果一个类型拥有一个所需的字段或者方法,那么就可以认为这个类型就是所需要的目标类型。这是因为 Python 是动态类型语言,不要求严格的继承体系。

简而言之,鸭子类型就是“如果一个对象看起来像鸭子,走起路来像鸭子,那么它就可以被看做是鸭子”。

如何自定义一个异常?

Python 中的所有异常都直接或者间接继承自 Exception 类,所以要实现一个自定义的一异常可以定义一个继承了 Exception 类的异常类。根据习惯,异常类一般使用 Error 字样作为类名的结尾。

如何定义一个枚举?

枚举可以使用 enum 库中提供的 Enum 类来定义。或者自定义一个类继承 Enum,可以在其中通过定义字段及其具体值来更加精确的控制枚举类的定义。

另外还可以搭配 enum 库中提供的 @unique 修饰器来确保自定义的枚举类中没有重复值的出现。

数据类和普通类有哪些区别?

根据 PEP-557 的定义,数据类就是一个带有默认值的可变命名元组。

相比普通类,数据类中所有的属性都是公有的,而且所有的属性都具有默认值并且可以被修改。数据类在定义以后会自动产生一个按照定义顺序为所有属性赋值的构造函数,以及 __repr__()__eq__() 两个方法。

数据类也支持继承,子类的属性会按照定义顺序添加进默认生成的构造函数;如果子类的属性与基类属性重名,那么子类的属性将会覆盖基类的同名属性。

数据类中的每个属性都会自动转化为 dataclass.Field 对象。

【熟练级别】如何动态的创建一个类?

在 Python 中所有类的基类都是内置的 type 类。type() 做为 class 的等效功能,在给定类名、基类名称和属性映射后即可创建一个新类。

注意考察“用于建立对象实例的类也是对象”的概念。

如何确保打开的文件一定会被关闭?其实现原理是什么?

可以使用 with 接收使用 open() 打开的文件,with 语句在结束的时候会保证已打开的文件关闭。

with 语句是通过构建一个进行资源管理的上下文管理传入的对象的。只要一个类实现了 __enter____exit__ 两个魔术方法,那么这个类所产生的所有对象都可以使用 with 语句来管理。

【熟练级别】如何在 Python 中使用异步 IO 功能?

在 Python 中一般会使用 asyncio 库来实现异步 IO 功能。异步 IO 允许在单线程中实现并发执行多个 IO 操作的能力,提升程序的性能和吞吐量。

异步函数是异步 IO 操作的核心。在 Python 没有引入 async/await 关键字之前,异步函数首先是一个生成器。这个生成器函数使用 async 库中提供的 @asyncio.coroutine 修饰器修饰,并在其中需要执行异步操作的位置使用 yield from 使当前异步函数进入等待而去执行 yield from 引导的另一个异步函数。当另一个异步函数执行结束以后,会自动再返回当前 yield from 的位置继续执行。这种使用 @asyncio.coroutine 修饰的异步函数需要放置在一个事件循环中执行。

当 Python 引入 async/await 关键字以后,异步函数就不需要使用 @async.coroutine 修饰器修饰了,只需要在定义函数的关键字 def 之前增加 async 关键字,然后使用 await 引导函数中的异步操作即可。在使用 async/await 语法时,主协程函数需要使用 asyncio 库中的 asyncio.run() 方法来启动。

Django 相关知识

什么是 Django ?有哪些突出的特点?

Django 是一个使用 Python 编写的 Web 应用框架,能够快速开发出易于维护和安全的网站。Django 拥有以下比较显著的特点:

  1. 为搜索引擎优化而优化。
  2. 速度快。
  3. 具有认证、内容管理和RSS订阅等功能。
  4. 高可扩展性,可以满足大流量的需求。
  5. 高度安全化。
  6. 多功能化,能够创建许多不同类型的网站。

Django 有哪些缺点?

  • 单体规模较大不适合小项目使用。
  • 过度封装,难于修改。
  • 强依赖于 Django 的 ORM。
  • 缺乏惯例,一切都需要明确定义。

什么是 Django 中的模型?

Django 中的模型由错处数据的必要字段和属性组成。模型是数据的单一、明确的信息来源。

简单描述一下 Django 的请求周期

Django 服务器在收到一个请求以后,会在项目定义的 URL 模式中寻找一个匹配的 URL,如果找不到这个匹配的 URL,那么 Django 将会产生一个 404 状态码;如果能够正确的找到匹配的 URL,那么就会执行这个 URL 对应的视图文件中的代码,生成对应于请求的响应。

什么是 Django Rest 框架?

Django Rest Framework 是一个可以基于 Django 快速创建 RESTful API 的框架。

Django 支持哪几种缓存策略?

Django 支持以下几种缓存策略:

  • 数据库缓存
  • 内存缓存
  • 文件系统缓存
  • Memcached

Flask 与 Sanic

什么是 Flask?

Flask 是一个轻量记得 Web 框架,用于快速构建 Web 应用。Flask 框架提供了简洁的 API 和灵活的扩展机制,具备简单易用和灵活可扩展的特点,适用于各种规模的应用开发。

Flask 有哪些优势?

Flask 属于微框架,所以其具备微框架小巧不依赖外部库的特点。除此之外,Flask 还具备以下特点:

  • 框架轻量,Flask 框架值提供了核心的功能,并非一个大而全的框架;
  • 简单易用,Flask 的设计理念即是尽量保持简单和易于理解,并提供了简洁的 API 和清晰的文档;
  • 灵活可扩展,Flask 提供了丰富的扩展机制和扩展组件,开发者可以根据应用的需要选择和集成;
  • 更新依赖小;
  • 专注于安全。

Django 和 Flask 有什么区别?

Flask 主要拥有以下特点:

  • 轻量级框架,主要依赖于 Werkzeugjinja2 两个库。
  • 适用于制作任何规模的应用以及 Web API。
  • 能够使用任何关系型数据库和非关系型数据库。

Django 的主要特点是:

  • 重量级 Web 框架,功能齐全,提供一站式解决方案。
  • 自带 ORM 和模板引擎,也支持选择使用 jinja2 等非官方引擎。
  • 自带 ORM 与关系型数据库强耦合,如果使用非关系型数据库需要选择使用第三方库。
  • 成熟稳定、开发效率高,有更强的封闭性,适合于开发企业级网站。
  • 拥有丰富的第三方库资源。

如何在 Flask 中访问会话?

会话数据都存储在服务器上,是客户端登录到服务器上时产生的,并在客户端与服务器断开的时候注销。Flask 中的会话可以使用以下方法访问和控制。

  • from flask import session,导入会话对象。
  • session['name'] = 'some name',在会话中添加键和所存储的值。
  • session.pop('name', None),删除保存在会话中的键。

Flask 框架中常用的组件有哪些?

  • flask-session,Session 存储控制。
  • flask-sqlalchemy,SQLAlchemy扩展。
  • flask-peewee,Peewee ORM扩展。
  • flask-oauth,提供 OAuth 支持的扩展。
  • flask-security,提供安全与验证功能的扩展。
  • flask-celery,提供 Celery 的接入。
  • flask-SocketIO,提供 WebSocket 功能支持。
  • flask_nameko,提供使用 Nameko 微服务的支持。
  • flask-apscheduler,提供定时任务功能支持。

Flask 中蓝图有什么作用?

Flask 中的蓝图可以实现模块化的应用,将一个大的 App 分割成专注于实现不同功能的模块。在应用中使用蓝图可以产生以下作用:

  • 将应用按照功能模块化。
  • 便于构建大型应用。
  • 优化项目结构。
  • 增强可读性,增加可维护性。

简述一下 Flask 中上下文的管理流程

Flask 中的上下文管理可以分为三个阶段:

  1. 请求抵达时:将请求相关的数据放入上下文管理中。
  2. 在视图函数处理中:从上下文管理中获取所需的值。
  3. 返回响应时:将上下文管理中的数据清除。

Flask 中请求上下文和应用上下文有哪些区别?

在 Flask 中 current_appg 是应用上下文,requestsession 是请求上下文。这两种上下文之间有以下区别:

  • 请求上下文保存的主要是客户端和服务端交互的数据,应用上下文保存的是应用在运行过程中所需的配置信息、数据库连接等。
  • 请求上下文主要是在视图函数执行中,使传入视图函数的参数得到有效的组织,同时将一些对象临时变为全局可访问的。而应用上下文则只是请求上下文中的一个对于 app 的代理,帮助请求获得当前应用的信息。

如何理解 Flask 中的请求钩子?

Flask 中的请求钩子是允许在处理请求的一些关键节点上执行一些额外处理的方法,请求钩子都是通过装饰器来实现的。Flask 中的请求钩子主要有以下四种:

  1. before_first_request:在处理第一个请求前运行。
  2. before_request:在每次请求之前运行。
  3. after_request:如果请求处理函数中没有抛出任何异常,那么就在每次请求之后运行。
  4. teardown_request:无论请求处理函数是否抛出异常,每次请求之后都会执行。

什么是 Sanic?

Sanic 框架是一个基于异步 IO 的 Web 框架,用于构建高性能的 Web 应用,因为其借鉴了 Flask 的简洁和易用性还有使用方式,所以又经常被称为异步版 Flask。Sanic 框架具有高性能、轻量级、简单易用的特点,十分适合于处理大量并发请求的场景。

Sanic 和 Flask 有什么区别?

  1. 异步 IO 支持:Sanic 框架基于异步 IO 实现,而 Flask 框架是基于同步 IO 的,所以 Sanic 框架可以处理大量的并发需求,拥有更好的性能和吞吐量。
  2. 性能表现:由于使用异步 IO, Sanic 框架在处理高并发请求时可以更好的利用资源,提供更快的响应。
  3. 中间件支持:Flask 框架提供了大量的中间件扩展,而 Sanic 框架因为起步较晚,中间件支持相对较少。

统计与大数据处理

一个给定的 $4 \times 4$ Numpy 矩阵,如何反转矩阵?

反转一个 Numpy 矩阵的步骤如下:

  1. 使用 np.array.flatten() 方法展平矩阵。对于非数组矩阵则需要使用 matrix.ravel() 方法进行展平。
  2. 从后向前重新形成新的数组。
  3. 使用 np.array.reshape() 方法重塑矩阵为 $4 \times 4$ 矩阵。

两个 Numpy 矩阵 如何相乘?

根据使用或者不使用 Numpy,总共可以有以下两种方法来实现矩阵的相乘:

  1. 使用 Numpy 时,可以使用 Numpy 数组的 .dot() 点积方法。
  2. 使用嵌套的 for 循环根据线性代数中的矩阵相乘的规则来逐元素进行运算。

如何转置一个 Numpy 矩阵?

根据使用或者不使用 Numpy,总共可以有以下三种方法可供选择:

  1. 使用嵌套的 for 循环生成新的转置矩阵。
  2. 通过构建一个元组列表,对元组列表使用 zip
  3. 使用 Numpy 时,可以使用 np.transpose() 或者 np.array.T

如何垂直堆叠两个 Numpy 矩阵?

m = np.vstack(x, y)

扩展问题
如何水平堆叠矩阵?

如何查看一个 Numpy 数组使用内存的大小?

1
2
m = np.empty((3, 2), np.uint32)
size = m.item_size * m.size

即使用每个元素占用内存的大小乘以元素个数。

如何用 08 的 9 个数字构造一个 $3 \times 3$ 的矩阵?

m = np.arange(9).reshape((3, -1))

如何避免复制操作来计算 $((A + B) \times (- \frac{A}{2}))$ ?

在矩阵计算操作时设定参数 out,指定计算结果的输出位置。

1
2
3
4
5
6
7
A = np.ones(3)*1
B = np.ones(3)*2
C = np.ones(3)*3
np.add(A,B,out=B)
np.divide(A,2,out=A)
np.negative(A,out=A)
print(np.multiply(A, B, out=A))

如何使用 Python 中的列表创建一个 Pandas 中的 series

s = pd.Series([1, 3, 5, np.nan, 6, 8])

如何使用 Python 中的列表创建一个 Pandas 中的 DataFrame

df = pd.DataFrame(["Gamer47","Shox","Simple"])

如何将新行追加到 DataFrame 中?

使用 pd.datafrae.append()函数,它可以将其他 DataFrame 的行追加给指定的 DataFrame 的末尾,并返回一个新的 DataFrame 对象。

什么是平均值、中位数和众数?

平均值:它是统计学中的一个重要概念。它是通过将两个或多个数字(变量)相加,然后将总和除以数字(变量)的总数而获得的数量或变量。

中位数:中位数也是观察一组数据平均情况的一种方法。它是一组数字的中间数字。结果有两种可能性,因为数据总数可能是奇数,也可能是偶数。如果总数是奇数,则将组中的数字从最小到最大排列。中位数恰好是位于中间的数,两侧的数量相等。如果总数是偶数,则按顺序排列数字并选择两个中间数字并加上它们然后除以 2,它将是该组的中位数。

众数:众数也是观察平均情况的方法之一。众数是一个数字,指在一组数字中出现最多的数字。有些数列可能没有任何众数;有些可能有两个众数,称为双峰数列。

什么是标准差、方差?

标准差:标准差用于衡量数据在统计数据中的离散程度。

方差:方差用于衡量数据集中各个数据点与平均值之间的差异程度。

什么是线性回归?

回归:回归是统计建模中的一种分析方法。这是衡量变量间关系的统计过程;它决定了一个变量和一系列其他自变量之间关系的强度。

线性回归:是预测分析中使用的统计技术之一,该技术将确定自变量对因变量的影响强度。

通过哪些基本统计数据可以表现两个变量之间的关联变化?

相关性是指两个或多个变量之间的关系程度。它用来衡量变量之间的线性关系强度和方向。相关性的取值范围在-1到1之间,其中-1表示完全负相关,0表示无相关性,1表示完全正相关。当相关性接近-1或1时,表示变量之间存在较强的线性关系;当相关性接近0时,表示变量之间没有线性关系。相关性分析可以帮助我们理解变量之间的关系,进行预测和决策。

协方差是一种统计量,用于衡量两个变量之间的关联程度。它衡量的是变量之间的线性关系,即它们如何一起变化。协方差可以是正值、负值或零,表示变量之间的关系是正相关、负相关或无关。

统计学中常用的抽样方法有哪些?

  • 聚类抽样:在聚类抽样方法中,总体将被分为群组或群集。
  • 简单随机抽样:这种抽样方法仅仅遵循随机分配。
  • 分层抽样:在分层抽样中,数据将分为组或分层。
  • 系统抽样:根据系统抽样方法,每隔k个成员,从总体中抽取一个。

什么是样本的置信区间?

置信区间是指由样本统计量所构造的总体参数的估计区间。置信区间展现的是这个参数的真实值有一定概率落在测量结果的周围的程度,也即误差范围。

什么是假设检验?

假设检验又称统计假设检验,是用来判断样本与样本、样本与总体的差异是由抽样误差引起还是本质差别造成的统计推断方法。常用的假设检验方法有Z检验、t检验、卡方检验、F检验等 。假设检验的基本思想是“小概率事件”原理,其统计推断方法是带有某种概率性质的反证法。

列举几种常用的概率分布

  • 二项分布:表示二项试验中n次试验有x次成功的概率分布;
  • 泊松分布:表示在一段特定时间或空间中一个事件发生x次的概率的概率分布;
  • 正态分布:一种连续型概率分布,其概率密度函数呈钟型,由均值μ和标准差σ确定;
  • 指数分布:一种连续型概率分布,在计算一个事件两次发生之间的时间或空间的概率时有用。

什么是小数定律、大数定律和中心极限定理?

小数定律:如果统计数据很少,那么事件就表现为各种极端情况,而这些情况都是偶然事件,跟它的期望值一点关系都没有。

大数定律:在随机事件的大量重复出现中,往往呈现几乎必然的规律,这个规律就是大数定律(伯努利定理)。通俗地说,在试验不变的条件下,重复试验多次,随机事件的频率近似于它的概期望值。

中心极限定理:样本的平均值约等于总体的平均值。不管总体是什么分布,任意一个总体的样本平均值都会围绕在总体的整体平均值周围,并且呈正态分布。

列举几个常见的统计分析模型

  • 相关分析:是研究现象之间是否存在某种依存关系,并对具体有依存关系的现象探讨其相关方向以及相关程度,是研究随机变量之间的相关关系的一种统计方法。
  • 回归分析:是确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。回归分析按照涉及的变量的多少,分为一元回归和多元回归分析。
  • 方差分析:又称“变异数分析”,用于两个及两个以上样本均数差别的显著性检验。 由于各种因素的影响,研究所得的数据呈现波动状。造成波动的原因可分成两类,一是不可控的随机因素,另一是研究中施加的对结果形成影响的可控因素。
  • 聚类分析:聚类分析指将物理或抽象对象的集合分组为由类似的对象组成的多个类的分析过程。聚类与分类的不同在于,聚类所要求划分的类是未知的。
  • 因子分析:因子分析是指研究从变量群中提取共性因子的统计技术。

如何处理缺失的数据?

  • 首先判断缺失数据是否有意义,如果没有意义或者缺失数据的比例超过80%直接去掉。
  • 如果缺失数据有规律,则需根据其变化规律来推测次缺失值;
  • 如果数据没有规律,则用其他值代替:
    • 如果数据符合正态分布,缺失值用期望值代替;
    • 如果数据是类型变量,则用默认类型值代替缺失值。

什么是幸存者偏差?

当取得资讯的渠道,仅来自于幸存者时(因为死人不会说话),此资讯可能会存在与实际情况不同的偏差。

大数据中的五个 V 是什么?

  • 卷(Volume):卷表示卷,即以高速率增长的数据量,即以PB为单位的数据量。
  • 速度(Velocity):速度是数据增长的速度。社交媒体在增长数据的速度中起着重要作用。
  • 多样性(Variety):多样性是指不同的数据类型,即各种数据格式,例如文本,音频,视频等。
  • 准确性(Veracity):准确性是指可用数据的不确定性。由于大量数据带来不完整和不一致,因此会出现准确性。
  • 价值(Value):价值是指将数据转化为价值。通过将访问的大数据转化为价值,企业可以产生收入。

机器学习与神经网络

什么是机器学习?

机器学习是一种人工智能的分支领域,它研究如何使计算机系统通过数据和经验不断改进和学习。机器学习的目标是通过构建和训练模型,使计算机能够自动识别模式、做出预测或做出决策,而无需明确地进行编程。机器学习算法可以分为监督学习、无监督学习和强化学习等不同类型,每种类型都有不同的应用场景和方法。机器学习在各个领域都有广泛的应用,如图像和语音识别、自然语言处理、推荐系统、金融预测等。

什么是神经网络?

神经网络是一种模仿人类神经系统的计算模型。它由大量的人工神经元(也称为节点)组成,这些神经元通过连接(也称为权重)相互传递信号。神经网络通过学习从输入数据中提取特征,并通过调整权重来进行模式识别和预测。神经网络可以分为多个层次,包括输入层、隐藏层和输出层。输入层接收原始数据,隐藏层对数据进行处理和转换,输出层生成最终的预测结果。神经网络的训练过程通常使用反向传播算法,通过计算神经网络的误差并反向调整权重,以使网络的输出尽可能接近预期结果。神经网络在机器学习和人工智能领域有广泛的应用,如图像和语音识别、自然语言处理、推荐系统等。

在机器学习的分类问题中有哪些常用的评价指标?

  • 混淆矩阵(Confusion Matrix),又称为可能性矩阵或错误矩阵。混淆矩阵的每一列代表了预测类别,每一行代表了数据的真实类别。分类问题的评价指标大多基于混淆矩阵计算得到的。
  • 准确率(Accuracy),识别对了的正例($TP$)与负例($TN$)占总识别样本的比例。缺点:类别比例不均衡时影响评价效果。公式为:$Acc=\frac{TP + TN}{TP + TN + FP + FN}$。
  • 精确率(Precision),识别正确的正例($TP$)占识别结果为正例($TP+FP$)的比例。公式为:$Pre=\frac{TP}{TP + FP}$。
  • 召回率(Recall),识别正确的正例($TP$)占实际为正例($TP+FN$)的比例。公式为:$Rec=\frac{TP}{TP + FN}$。
  • F1值是召回率R和精度P的加权调和平均,顾名思义即是为了调和召回率R和精度P之间增减反向的矛盾,对R和P进行加权调和。公式为:$F1 = \frac{2 \times Pre \times Rec}{Pre + Rec}$。
  • P-R曲线通过取不同的分类阈值,分别计算当前阈值下的模型$Pre$值和$Rec$值,以$Pre$值为纵坐标,$Rec$值为横坐标,将算得的一组$Pre$值和$Rec$值画到坐标上,就可以得到P-R曲线。当一个模型的P-R曲线完全包住另一个模型的P-R曲线,则前者的性能优于后者(如A>C,B>C)。
  • **ROC(Receiver Operating Characteristic)**也称受试者工作特征。以FPR(假正例率:假正例占所有负例的比例)为横轴,TPR(召回率)为纵轴,绘制得到的曲线就是ROC曲线。与PR曲线相同,曲线下方面积越大,其模型性能越好。
  • AUC,ROC曲线下的面积即为AUC。面积越大代表模型的分类性能越好。随机挑选一个正样本以及负样本,算法将正样本排在所有负样本前面的概率就是AUC值。AUC 是排序模型中最为常见的评价指标之一。公式为:$AUC=\frac{\sum_{i=1}^{N} Rank_i - N \cdot \frac{N + 1}{2}}{M \cdot N}$。

在机器学习的回归问题中有哪些常用的评价指标?

  • MAE(Mean Absolute Error),MAE是平均绝对误差,又称L1范数损失。通过计算预测值和真实值之间的距离的绝对值的均值,来衡量预测值与真实值之间的真实距离。公式为:$MAE=\frac{1}{n}\sum_{i=1}^{n}|f(x_i) - y_i|$。
  • MSE(Mean Square Error),MSE是真实值与预测值的差值的平方然后求和平均。通过平方的形式便于求导,所以常被用作线性回归的损失函数。公式为:$MSE=\frac{1}{n}\sum_{i=1}^{n}(f(x_i) - y_i)^2$。
  • RMSE(Root Mean Square Error),RMSE衡量观测值与真实值之间的偏差。常用来作为机器学习模型预测结果衡量的标准。 受异常点影响较大,鲁棒性比较差。公式为:$RMSE=\sqrt{\frac{1}{n}\sum_{i=1}^{n}(f(x_i) - y_i)^2}$

在机器学习的排序问题中有哪些常用的评价指标?

  • AUC,与分类问题中的 AUC 相同。
  • MAP(Mean Average Precision),全局平均准确率,其中AP表示单用户TopN推荐结果的平均准确率。公式为: $AP = \frac{\sum_{n=1}^{R}Pre@N \cdot rel(N)}{R}$。AP衡量的是整个排序的平均质量。对全局所有用户的AP取平均值就是MAP。公式为:$MAP=\frac{1}{n}\sum_{n=1}^{N}AP_i$。
  • NDCG(归一化折损累计增益)IDCG,表示推荐系统对所有用户推荐结果DCG的一个平均值,由于每个用户的排序列表不一样,所以先对每个用户的DCG进行归一化,再求平均。其归一化时使用的分母就是IDCG,指推荐系统为某一用户返回的最好推荐结果列表,即假设返回结果按照相关性排序,。
    • CG(累计收益),模型会给推荐的每个item打分表示与当前用户的相关性。假设当前推荐item的个数为N个,将这N个item的相关分数进行累加,就是当前用户的累积增益 $CG_N=\sum_{i=1}^{N}rel_i$。
    • DCG(折损累计增益),在 CG 基础上引入位置影响因素,即DCG,位置靠后的结果进行加权处理:$DCG_N=\sum_{i=1}^{N}\frac{rel_i}{log_2(i+1)}$。
  • MRR(Mean Reciprocal Rank),MRR平均倒数排名,是一个国际上通用的对搜索算法进行评价的机制,即第一个结果匹配,分数为1,第二个匹配分数为0.5,第n个匹配分数为1/n,如果没有匹配的句子分数为0。最终的分数为所有得分之和。公式为:$MRR=\frac{1}{N}\sum_{i=1}^{N}\frac{1}{p_i}$。

在机器学习的聚类问题中有哪些常用的评价指标?

  • 紧密度(Compactness),每个聚类簇中的样本点到聚类中心的平均距离。紧密度越小,表示簇内的样本点越集中,样本点之间聚类越短,也就是说簇内相似度越高。
  • 分割度(Seperation),每个簇的簇心之间的平均距离。分割度值越大说明簇间间隔越远,分类效果越好,即簇间相似度越低。
  • 轮廓系数 (Silhouette Coefficient),对于一个样本集合,它的轮廓系数是所有样本轮廓系数的平均值。轮廓系数的取值范围是 $[-1, 1]$,同类别样本距离越相近,不同类别样本距离越远分数越高。聚类的总体轮廓系数公式为:$SC=\frac{1}{N}\sum_{i=1}^{N}SC(d_i)$。
  • 兰德系数(Rand index),兰德系数是使用真实label对聚类效果进行评估,评估过程和混淆矩阵的计算类似。

什么是损失函数?常用的损失函数有哪些?

损失函数(Loss Function)是监督学习过程中关键的一个组成部分,用来衡量模型的预测值与真实值的之间的差距,度量模型预测错误的程度,为模型的迭代优化指明方向。

常见的损失函数有:

  • 用于分类问题的损失函数:
    • 0-1损失函数:0-1损失是指预测值和目标值不相等为1,否则为0。
    • 交叉熵损失函数:交叉熵损失函数经常用于分类问题中,特别是在神经网络做分类问题时,也经常使用交叉熵作为损失函数。交叉熵损失函数的输入数据通常是softmax或者sigmoid函数的输出。交叉熵当损失函数时,在模型效果差的时候学习速度比较快,在模型效果好的时候学习速度变慢。
    • 对数损失函数:对数损失函数本质上是一种似然函数,主要在逻辑回归中使用。假设样本预测值和实际值的误差符合高斯分布,采用极大似然估计的方法,取对数得到损失函数。对数损失函数的健壮性不强,对噪声敏感。
    • Hinge 损失函数(Hinge Loss):hinge损失函数中样本如果被正确分类,则损失为0,否则损失就为 $1-y \cdot f(x)$。支持向量机SVM使用hinge损失函数。
  • 用于回归问题的损失函数:
    • 绝对值损失函数(MAE):平均绝对误差即L1损失函数,平均绝对误差指的就是模型预测值 $f(x)$ 与样本真实值 $y$ 之间距离的平均值。MAE 大部分情况下梯度都是相等的,这意味着即使对于小的损失值,其梯度也是大的。MAE不利于函数的收敛和模型的学习。
    • 平方损失函数(MSE):均方误差即L2损失,均方误差指的就是模型预测值 $f(x)$ 与样本真实值 $y$ 之间距离平方的平均值。MSE 曲线的特点是光滑连续、可导,便于使用梯度下降算法,是比较常用的一种损失函数。而且,MSE 随着误差的减小,梯度也在减小,这有利于函数的收敛。
    • Huber 损失函数(Huber Loss):Huber Loss 结合了 MSE 和 MAE 损失,在误差接近 0 时使用 MSE,使损失函数可导并且梯度更加稳定;在误差较大时使用 MAE 可以降低噪声数据的影响,使训练对 outlier 更加健壮。缺点是需要额外地设置一个 $\delta$ 超参数。

解决过拟合问题的方法有哪些?

  • 增加数据、添加噪声。
  • early stooping。
  • 数据均衡(过采样、将采样)。
  • 正则化(L1,L2)。
    1. 解空间形状:加入正则化项即为约束条件,形成不同形状的约束解空间。
    2. 导数:L2的导数为 $2X$,平滑。L1导数为 $X,-X$,存在突变的极值点
    3. 先验:加入正则化项相当于引入参数的先验知识:L1引入拉普拉斯,L2引入高斯分布。L1可以做到特征筛选和得到稀疏解。L2加速训练
  • Dropout,减小参数规模,随机丢弃产生不同网络,形成集成,解决过拟合,加速训练。
  • Batch normolization,加快训练、消除梯度消失(爆炸)、防止过拟合 不适用太小batch、CNN。

什么是随机森林法?

随机森林法是一种集成学习方法,用于解决分类和回归问题。它由多个决策树组成,每个决策树都是独立训练的。随机森林法的主要思想是通过随机选择特征子集和样本子集来构建多个决策树,然后通过集成多个决策树的结果来进行预测。

随机森林法的训练过程如下:

  1. 从原始数据集中随机选择一部分样本(有放回地抽样),形成一个样本子集。
  2. 从所有特征中随机选择一部分特征,形成一个特征子集。
  3. 使用样本子集和特征子集来训练一个决策树模型。
  4. 重复步骤1到步骤3多次,构建多个独立的决策树。
  5. 对于分类问题,通过投票或取平均值来决定最终的预测结果;对于回归问题,通过取平均值来决定最终的预测结果。

处理海量数据常用的都有哪些方法?

  • Hash法:hash映射,hash统计+堆/归并/快速排序。
  • 双层桶法:重找中位数(划分数据、统计个数)。
  • Bit-map:为每个数分配bit,遍历改变状态。
  • Trie树、数据库。
  • 外排序。
  • map reduce。

什么叫张量?

神经网络中使用的数据一般保存在Numpy数组中,也称为张量(tensor)。张量在机器学习领域非常重要,它是一个数据容器,其中所包含的数据基本上全部都是数值数据。矩阵是一个二维张量,张量是矩阵向任意维度的推广。张量的维度一般也称为

仅包含一个数字的张量称为标量,也称为零维张量或者0D张量。由数字组成的数组称为向量或者一维张量(1D张量),一维张量只有一个轴。

张量一般由三个关键属性来定义:

  • :也就是轴的个数,在 Python 的 Numpy 中,也称为张量的 ndim
  • 形状:一个整数元组,用于表示张量沿每个轴的维度大小。例如一个 $3 \times 5$(三行五列)的矩阵,其形状为 $(3, 5)$,不同维度的张量的形状包含的元组元素个数不同。
  • 数据类型:张量中所包含的数据类型,在 Python 中称为 dtype

卷积核是什么?滤波器的作用是什么?

卷积核,在给定输入矩阵后,输出矩阵中的每一个元素都是输入矩阵中的一个小区域中元素的加权平均,这个权重值由一个函数定义,这个函数就称为卷积核。

滤波器,即卷积核,英文为filter,滤波器针对具备特定特征的矩阵有很高的输出,对其他矩阵的输出很低,这就模仿了神经元的激活。滤波器的权重值就相当于人脑的记忆。

数据的预处理都有哪些方法?

数据预处理的目的是使原始数据更加适合于使用神经网络处理,数据预处理的方法包括向量化、标准化、处理缺失值和特征提取。

  • 向量化:神经网络的所有输入和目标都必须是浮点张量。任何数据,包括声音、图像、文字都必须首先转换为张量,这个步骤叫做数据向量化。
  • 值标准化:在完成向量化后的数据,一般需要将取值相对较大的数据或者异质数据进行标准化。向神经网络输入的数据一般应该具有取值较小(大部分值都在 $0∼1$ 范围之内)和同质性(所有特征的取值应该在大致相同的范围)两个特征。
  • 处理缺失值:用于神经网络的数据中可能会存在缺失值,但一般对于神经网络来说,将缺失值设置为 0 是安全的。只要 0 不是一个有意义的值,神经网络就可以忽略这个值。但是需要注意的是,如果神经网络没有学会处理缺失值,那么在应用到带有缺失值的实际数据中时,就会出现潜在的问题。这种情况下应该人为生成带缺失值的训练样本进行补充训练。
  • 特征提取:特征工程是指在数据输入模型之前,先利用算法对数据进行硬编码转换,以改善模型的效果。多数情况下,呈现给模型的数据应该便于模型进行学习。虽然针对现代深度学习,大部分的特征工程都是不需要的,但是良好的特征仍然可以让你用更少的资源和数据解决问题。

$1 \times 1$ 的卷积核有哪些意义?

一般来说,卷积核的大小必须大于 1 才有提升感受野的作用。但是 $1 \times 1$ 的卷积核在许多神经网络,例如 NIN、Googlenet中都有广泛的应用。

$1 \times 1$ 卷积核一般认为可以用于以下目的:

  1. 实现跨通道的交互和信息整合。
  2. 进行卷积核通道数的升维和降维。
  3. 减少卷积核参数。
  4. 对于单通道特征图可以实现多个特征图的线性组合。
  5. 实现与全连接层等价的效果。

池化的作用是什么?

池化通常有两种:平均池化和最大池化。池化主要用于压缩特征图,平均池化会使用池中数据的平均值来代表池数据,而最大池化则是使用池中数据的最大值。池化相当于对特征图进行分区,然后提取每一个区的特征值来形成新的压缩过的特征图。池化也常称为下采样(downsampling)。

对于一般卷积神经网络来说,常在卷积层后使用 MaxPooling2D((2, 2)) 进行池化以压缩特征图,降低运算压力。

全连接层的常见用途是什么?

全连接层,也称为密集连接层,全连接层主要实现 output=activation(dot(input,kernel)+bias) 的操作,其中 activation 是按逐个元素计算的激活函数。全连接层的输入形状为 (batch_size, ..., input_dim) ,输出形状为 (batch_size, ..., units)

全连接层的“全连接”表示上一层的每一个神经元都与下一层的每一个神经元是相互连接的。加入全连接层是学习特征之间非线性组合的有效办法,例如将卷积层和池化层提取出来的特征进行特征之间的组合。


索引标签
面试题
Python