人工智能(AI)正在深刻地改变着我们的生活和工作方式。作为一名有志于投身AI领域的学习者,仅仅追逐高薪和热门技术是不够的。我们需要对人工智能领域有一个全面而深刻的理解,形成自己的判断,才能做出明智的选择,并在这个快速发展的领域中找到自己的位置。本文将以NumPy、Pandas和Matplotlib这三大Python数据科学库为基石,结合详实的案例和图表,为你构建一套系统化的AI知识体系,助你成为一名合格的AI工程师。
一、人工智能概览
人工智能并非遥不可及的未来科技,而是已经渗透到我们日常生活中的方方面面。从语音识别、机器翻译到图像识别、智能风控,AI的身影无处不在。一个经典的AI定义是:“智能主体可以理解数据及从中学习,并利用知识实现特定目标和任务的能力。”
在技术层面,机器学习是目前人工智能的核心技术。机器学习是指非显式的计算机程序可以从数据中学习,以此提高处理任务的水平。常见的任务包括分类(例如,使用逻辑回归模型判断邮件是否为垃圾邮件)和回归预测(例如,使用线性回归模型预测房价)。深度学习作为机器学习的一个子方向,通过搭建深层的神经网络模型来处理复杂任务,是当前的热门技术。
从应用领域来看,人工智能在语言识别、自然语言处理、图像识别、数据挖掘、推荐系统、智能风控、机器人等众多领域都有着广泛的应用。值得注意的是,不同应用领域在技术层面虽然具有一定的共通性,但在实际应用场景中,对业务知识、算法和工程的要求却存在相当大的差异。
二、基础知识与工具准备
要进入人工智能领域,扎实的编程和数学基础是必不可少的。AI算法工程师首先是一名程序员,掌握编程实现方法才能将理论知识转化为实际应用。而数学则是人工智能理论的基石,对算法原理的理解和进阶至关重要。
在人工智能领域,Python已经成为最受欢迎的编程语言之一,原因如下:
- 语法简单易懂,适合零基础入门。
- 拥有丰富的机器学习库,方便机器学习的开发。
- 在机器学习领域有较高的使用率,意味着社区庞大,应用范围广,市场上有较多的工作机会。
在数学方面,初学者如果数学基础比较薄弱,可以先补习“数学的最小必要知识”,例如线性代数的矩阵运算、高等数学的梯度求导、概率的条件概率和贝叶斯定理等。这些知识可以帮助理解大部分的算法。
三、NumPy科学计算库
NumPy(Numerical Python)是Python中用于数值计算的基石。它提供了一个强大的N维数组对象,以及用于处理这些数组的各种函数。NumPy的高效数组运算能力使其成为数据分析和科学计算的首选工具。
- 数组创建:NumPy提供了多种创建数组的方法,例如:
将Python列表转换为NumPy数组:
import numpy as np l = [1, 3, 5, 7, 9] arr = np.array(l) print(arr)
使用内置函数创建数组:
arr1 = np.ones(10) # 创建包含10个1的数组 arr2 = np.zeros(10) # 创建包含10个0的数组 arr3 = np.full(shape=[2, 3], fill_value=2.718) # 创建一个2x3的数组,所有元素都为2.718 arr4 = np.arange(start=0, stop=20, step=2) # 创建一个等差数列数组,从0到20,步长为2 arr5 = np.linspace(start=0, stop=9, num=10) # 创建一个等差数列数组,从0到9,包含10个元素 arr6 = np.random.randint(0, 100, size=10) # 创建一个包含10个0到100之间随机整数的数组 arr7 = np.random.randn(5) # 创建一个包含5个符合正态分布的随机数的数组 arr8 = np.random.random(size=5) # 创建一个包含5个0到1之间随机浮点数的数组
- 数组属性查看:NumPy数组具有多种属性,可以帮助我们了解数组的结构和数据类型:
ndim
:数组的轴数(维度)。size
:数组元素的总数。dtype
:数组元素的数据类型。itemsize
:数组中每个元素的大小(以字节为单位)。
- 文件IO操作:NumPy允许我们将数组保存到文件中,并在需要时重新加载:
保存数组:
x = np.random.randn(5) y = np.arange(0, 10, 1) np.save("x_arr", x) # 将数组x保存到x_arr.npy文件中 np.savez("some_array.npz", xarr=x, yarr=y) # 将数组x和y保存到some_array.npz文件中
读取数组:
np.load('x_arr.npy') # 从x_arr.npy文件中加载数组 np.load('some_array.npz')['yarr'] # 从some_array.npz文件中加载数组y
读写csv、txt文件:
arr = np.random.randint(0, 10, size=(3, 4)) np.savetxt("arr.csv", arr, delimiter=',') # 将数组保存到arr.csv文件中,使用逗号作为分隔符 np.loadtxt("arr.csv", delimiter=',', dtype=np.int32) # 从arr.csv文件中加载数组,使用逗号作为分隔符,数据类型为int32
- 数据类型:NumPy支持多种数据类型,包括整数、浮点数和字符串。我们可以使用
dtype
参数在创建数组时指定数据类型,也可以使用astype
方法进行数据类型转换。 - 数组运算:NumPy允许我们对数组进行各种算术运算和逻辑运算。这些运算可以逐元素地进行,也可以将标量值传播到整个数组。
- 数组的赋值,浅拷贝,深拷贝:理解NumPy数组的赋值、浅拷贝和深拷贝对于避免意外修改数据至关重要。
- 赋值操作只是创建了一个指向原始数组的引用,修改赋值后的数组会影响原始数组。
- 浅拷贝创建了一个新的数组对象,但新数组和原始数组共享相同的数据。修改浅拷贝后的数组会影响原始数组。
- 深拷贝创建了一个完全独立的数组对象,新数组和原始数组互不影响。
- 索引、切片和迭代:NumPy提供了灵活的索引和切片机制,可以方便地访问和修改数组中的元素。我们还可以使用迭代器来遍历数组中的所有元素。
- 形状操作:NumPy提供了多种形状操作方法,可以改变数组的形状、转置数组、堆叠数组和拆分数组。
- 广播机制:当两个数组的形状不兼容时,NumPy会尝试通过广播机制将它们扩展到相同的形状,然后再进行运算。广播机制可以简化代码,提高效率。
- 通用函数:NumPy提供了大量的通用函数,可以对数组进行各种数学运算、排序、集合运算和统计运算。
- 线性代数:NumPy的
numpy.linalg
模块提供了丰富的线性代数函数,可以进行矩阵乘积、求逆、行列式、特征值和特征向量等运算。
四、pandas数据分析库
pandas是Python中用于数据分析的核心库。它提供了快速、灵活和明确的数据结构,旨在简化和加速数据处理过程。
- 数据结构:pandas主要有两种数据结构:
- Series:一维带标签的数组,类似于NumPy的数组,但具有更强大的索引功能。
- DataFrame:二维表格型数据结构,类似于SQL表格或Excel表格,可以存储多种数据类型的数据。
- 数据查看:pandas提供了多种方法来查看DataFrame的属性、概览和统计信息:
head(n)
:显示DataFrame的前n行,默认为5行。tail(n)
:显示DataFrame的后n行,默认为5行。shape
:查看DataFrame的形状,返回行数和列数。dtypes
:查看DataFrame各列的数据类型。index
:查看DataFrame的行索引。columns
:查看DataFrame的列索引。values
:查看DataFrame的值,返回一个二维ndarray数组。describe()
:查看DataFrame数值型列的汇总统计信息,包括计数、平均值、标准差、最小值、四分位数和最大值。info()
:查看DataFrame的列索引、数据类型、非空计数和内存信息。
- 数据输入与输出:pandas可以从多种数据源读取数据,并将数据写入到多种格式的文件中:
- CSV:使用
read_csv
函数读取CSV文件,使用to_csv
方法将DataFrame写入CSV文件。 - Excel:使用
read_excel
函数读取Excel文件,使用to_excel
方法将DataFrame写入Excel文件。 - SQL:使用
read_sql
函数从SQL数据库读取数据,使用to_sql
方法将DataFrame写入SQL数据库。 - HDF5:使用
read_hdf
函数读取HDF5文件,使用to_hdf
方法将DataFrame写入HDF5文件。
- CSV:使用
- 数据选取:pandas提供了多种数据选取方法,可以根据字段、标签、位置和布尔索引来选择数据。
- 数据集成:pandas提供了多种将Series和DataFrame对象组合在一起的功能,包括concat、append和merge。
- 数据清洗:pandas提供了多种数据清洗方法,可以处理重复数据、空数据和异常值。
- 数据转换:pandas提供了多种数据转换方法,可以替换轴和元素、应用函数和进行重排随机抽样。
- 数据重塑:pandas提供了多种数据重塑方法,可以转置DataFrame、堆叠和取消堆叠数据。
- 数学和统计方法:pandas提供了大量的数学和统计方法,可以计算简单统计指标、索引标签、位置获取、更多统计指标和高级统计指标。
- 数据排序:pandas提供了多种数据排序方法,可以根据索引列名或属性值进行排序。
- 分箱操作:pandas提供了分箱操作,可以将连续数据转换为分类数据。
- 分组聚合:pandas提供了强大的分组聚合功能,可以根据一个或多个列对数据进行分组,并对每个组应用聚合函数。
- 时间序列:pandas提供了强大的时间序列分析功能,可以进行时间戳操作、时间戳索引和常用时间序列方法。
五、Matplotlib数据可视化
Matplotlib是Python中最常用的绘图库,可以创建各种静态、动态和交互式图表。
- 基础知识:Matplotlib的基本绘图流程包括:
- 创建图形(Figure)和轴域(Axes)。
- 在轴域上绘制各种图形,例如折线图、散点图、柱状图等。
- 设置坐标轴刻度、标签和标题。
- 添加图例。
- 移动脊柱。
- 保存图片。
- 风格和样式:Matplotlib允许我们自定义图表的风格和样式,包括颜色、线型、点形、线宽和透明度。
- 多图布局:Matplotlib提供了多种多图布局方式,包括子视图、嵌套和多图布局分格显示。
- 文本、注释、箭头:Matplotlib允许我们在图表中添加文本、注释和箭头,以增强图表的可读性。
- 常用视图:Matplotlib支持多种常用视图,包括折线图、柱状图、极坐标图、直方图、箱形图、散点图、饼图、甜甜圈、热力图、面积图和蜘蛛图。
- 3D图形:Matplotlib可以创建简单的3D图形,包括三维折线图散点图和三维柱状图。
六、案例实战:数据分析师招聘数据分析
本文将以一个数据分析师招聘数据分析案例来演示如何使用Matplotlib进行数据可视化。
各城市对数据分析岗位的需求量:
plt.figure(figsize=(12, 9)) cities = job['city'].value_counts() plt.barh(y=cities.index[::-1], width=cities.values[::-1], color='#3c7f99') plt.box(False) plt.title(label=' 各城市数据分析岗位的需求量 ', fontsize=32, weight='bold', color='white', backgroundcolor='#c5b783', pad=30) plt.tick_params(labelsize=16) plt.grid(axis='x', linewidth=0.5, color='#3c7f99') plt.show()
不同领域对数据分析岗的需求量:
industry_index = job["industryField"].value_counts()[:10].index industry = job.loc[job["industryField"].isin(industry_index), "industryField"] plt.figure(figsize=(12, 9)) plt.barh(y=industry_index[::-1], width=pd.Series.value_counts(industry.values).values[::-1], color='#3c7f99') plt.title(label=' 细分领域数据分析岗位的需求量(取前十) ', fontsize=32, weight='bold', color='white', backgroundcolor='#c5b783', ha='center', pad=30) plt.tick_params(labelsize=16) plt.grid(lw=0.5, color='#3c7f99', ls='--') plt.show()
各城市薪资状况:
plt.figure(figsize=(12, 9)) city_salary = job.groupby("city")["salary"].mean().sort_values() plt.bar(x=city_salary.index, height=city_salary.values, color=plt.cm.RdBu_r(np.linspace(0, 1, len(city_salary)))) plt.title(label=' 各城市的薪资水平对比 ', fontsize=32, weight='bold', color='white', backgroundcolor='#3c7f99') plt.tick_params(labelsize=16) plt.grid(axis='y', linewidth=0.5, color='black') plt.yticks(ticks=np.arange(0, 25, step=5), labels=['', '5k', '10k', '15k', '20k']) plt.box(False) plt.show()
工作经验与薪水关系:
work_salary = job.pivot_table(index="city", columns="workYear", values="salary") work_salary = work_salary[["应届毕业生", "1-3年", "3-5年", "5-10年"]].sort_values(by='5-10年', ascending=False) data = work_salary.values data = np.repeat(data, 4, axis=1) plt.figure(figsize=(12, 9)) plt.imshow(data, cmap='RdBu_r') plt.yticks(np.arange(13), work_salary.index) plt.xticks(np.array([1.5, 5.5, 9.5, 13.5]), work_salary.columns) h, w = data.shape for x in range(w): for y in range(h): if (x % 4 == 0) and (~np.isnan(data[y, x])): text = plt.text(x + 1.5, y, round(data[y, x], 1), ha="center", va="center", color='r', fontsize=16) plt.colorbar(shrink=0.85) plt.tick_params(labelsize=16) plt.show()
学历要求:
education = job["education"].value_counts(normalize=True) plt.figure(figsize=(9, 9)) _ = plt.pie(education, labels=education.index, autopct='%0.2f%%', wedgeprops=dict(linewidth=3, width=0.5), pctdistance=0.8, textprops=dict(fontsize=20)) _ = plt.title(label=' 学历要求 ', fontsize=32, weight='bold', color='white', backgroundcolor='#c5b783') plt.show()
技能要求:
def get_level(x): if x["Python/R"] == 1: x["skill"] = "Python/R" elif x["SQL"] == 1: x["skill"] = "SQL" elif x["Excel"] == 1: x["skill"] = "Excel" elif x['SPSS/SAS'] == 1: x['skill'] = 'SPSS/SAS' else: x["skill"] = "其他" return x job = job.apply(get_level, axis=1) x = job.loc[job.skill != '其他'][['salary', 'skill']] cond1 = x['skill'] == 'Python/R' cond2 = x['skill'] == 'SQL' cond3 = x['skill'] == 'Excel' cond4 = x['skill'] == 'SPSS/SAS' plt.figure(figsize=(12, 8)) plt.title(label=' 不同技能的薪资水平对比 ', fontsize=32, weight='bold', color='white', backgroundcolor='#c5b783', pad=30) plt.boxplot(x=[job.loc[job.skill != '其他']['salary'][cond1], job.loc[job.skill != '其他']['salary'][cond2], job.loc[job.skill != '其他']['salary'][cond3], job.loc[job.skill != '其他']['salary'][cond4]], vert=False, labels=["Python/R", "SQL", "Excel", 'SPSS/SAS']) plt.tick_params(axis="both", labelsize=16) plt.grid(axis='x', linewidth=0.75) plt.xticks(np.arange(0, 61, 10), [str(i) + "k" for i in range(0, 61, 10)]) plt.box(False) plt.xlabel('工资', fontsize=18) plt.ylabel('技能', fontsize=18) plt.show()
大公司对技能要求:
skill_count = job[job['companySize'] == '2000人以上'][['Python', 'SQL', 'Tableau', 'Excel', 'SPSS/SAS']].sum() plt.figure(figsize=(9, 6)) plt.bar(np.arange(5), skill_count, tick_label=['Python/R', 'SQL', 'Tableau', 'Excel', 'SPSS/SAS'], width=0.5, color=plt.cm.RdBu_r(skill_count / skill_count.max())) _ = plt.title(label=' 大公司对技能的要求 ', fontsize=32, weight='bold', color='white', backgroundcolor='#c5b783', pad=30) plt.tick_params(labelsize=16, ) plt.grid(axis='y') plt.box(False) plt.show()
不同规模的公司在招人要求上的差异:
from matplotlib import gridspec workYear_map = { "5-10年": 5, "3-5年": 4, "1-3年": 3, "1年以下": 2, "应届毕业生": 1} color_map = { 5: "#ff0000", 4: "#ffa500", 3: "#c5b783", 2: "#3c7f99", 1: "#0000cd"} cond = job.workYear.isin(workYear_map) job = job[cond] job['workYear'] = job.workYear.map(workYear_map) job['companySize'] = job['companySize'].astype('category') list_custom = ['2000人以上', '500-2000人', '150-500人', '50-150人', '15-50人', '少于15人'] job['companySize'].cat.reorder_categories(list_custom, inplace=True) job.sort_values(by='companySize', inplace=True, ascending=False) plt.figure(figsize=(12, 11)) gs = gridspec.GridSpec(10, 1) plt.subplot(gs[:8]) plt.suptitle(t=' 不同规模公司的用人需求差异 ', fontsize=32, weight='bold', color='white', backgroundcolor='#3c7f99') plt.scatter(job.salary, job.companySize, c=job.workYear.map(color_map), s=(job.workYear * 100), alpha=0.35) plt.scatter(job.salary, job.companySize, c=job.workYear.map(color_map)) plt.grid(axis='x') plt.xticks(np.arange(0, 161, 10), [str(i) + "k" for i in range(0, 161, 10)]) plt.xlabel('工资', fontsize=18) plt.box(False) plt.tick_params(labelsize=18) plt.subplot(gs[9:]) x = np.arange(5)[::-1] y = np.zeros(len(x)) s = x * 100 plt.scatter(x, y, s=s, c=color_map.values(), alpha=0.3) plt.scatter(x, y, c=color_map.values()) plt.box(False) plt.xticks(ticks=x, labels=list(workYear_map.keys()), fontsize=14) plt.yticks(np.arange(1), labels=[' 经验:'], fontsize=18) plt.show()
七、总结
NumPy、Pandas和Matplotlib是Python数据科学的三大基石。掌握这三大库,你就可以进行高效的数据处理、数据分析和数据可视化。结合实际案例,可以让你更好地理解和运用这些知识,为进入人工智能领域打下坚实的基础。