期末周来袭,写下本文章以供各大网友进行机器学习期末总复习。
根据实验报告与所学内容,本文章将分为七大部分,望网友看完能对机器学习能有进一步的理解。
- pandas入门
- matplotlib可视化
- 数据预处理
- 机器学习经典算法——回归、分类、聚类
- 机器学习的结果评价
- 机器学习的扩展
1.pandas入门
pandas是机器学习中常用的、对数据集进行操作的简单易上手的python库,在许多数据处理方面经常与numpy库一起使用。
pandas的操作对象经常使用的有Series(一维表)和DataFrame(二维表)。
Series也被称为一维表,可以看成表格中的一列或者列向量。可以用pandas里面的Series构造,
下面是个案例:
import pandas as pd
data=pd.Series([1,2,3,4,5])
print(data)
可以很明显的看出,Series产生的是一列数字,左边的0,1,2,3,4分别对应每一行数字的行索引(索引的意思就是序号的意思,用来方便快速查找某一行或某一列数据),可以利用行索引来对Series进行切分或读取(像list列表的操作),例如:
可以很明显的看出来已经创建的Series中行索引为2的对应的数据是3,也可以用冒号(:)进行切分:
还可以自定义一维表的行索引(index):
import pandas as pd
## 这里一定要注意自定义的列索引的个数要与一维数组的行数相对应,不然会报错
data=pd.Series([1,2,3,4,5],index=['a', 'b', 'c', 'd', 'f'])
print(data)
可以看出左边的行索引已经换成了自定义的a,b,c,d,f。
这里就可以用自定义的行索引进行访问了:
还可以用语句来进行访问(常考):
这个语句有两层,内层的data[:]的意思是访问data所有的值,然后将大于1的值筛选出来。以此类推在DataFrame里会有更复杂的行索引加列索引访问操作,后面会仔细再说。
Series有两个常用的属性,index和values,从名称可以看出来属性的意思,一个是一维表的列标签,一个是一维表的具体值。如下:
Series也可以进行计算:
以上可以看出一维表的操作与列表很相似,在学习初可以暂时把一维表看作是列表进行操作,接下来我们来看看DataFrame是什么。
DataFrame是机器学习算法中最常用到的数据集的表示方式,可以将它看成二维表,顾名思义,其实就是一个表格,分为行和列,也有对应的行索引(index)和列索引(columns),其实就是多个一维表组合到一起就成了二维表,每个一维表都赋上对应的行索引名称,就成为了DataFrame(二维表)。接下来看个实例:
# -*- coding: utf-8 -*-
import pandas as pd
# 第一种创建方法:使用字典(python里面的字典就是键值对,用{}表示(列表用[]表示)
# 键值对就是一个键(key)对应一个值(value)和一维表里面的行索引和对应的值一个意思)
data1 = {'a': [1, 2], 'b': [2, 3], 'c': [3, 4]}
df = pd.DataFrame(data1)
print(df)
# 第二种创建方法是最常用到的,通过读取外部的csv文件或xlsx文件(csv以逗号‘,’作为每个数据的分隔符,xlsx以空白格为分隔符)
# 读取的结果就是DataFrame格式的二维表,方便后续进行预处理,训练模型等操作
data2 = pd.read_csv('housing.csv') # csv文件读取方式,括号里面是要读取文件的地址,绝对地址和相对地址都可以
data3 = pd.read_excel('result1_1.xlsx') # xlsx文件读取方式
print(data2)
print(data3)
例如实验一的第一题:
DataFrame有以下属性,可以通过在DataFrame后面加.(对应的属性名)调用
属性名 | 返回值 |
values | 元素 |
index | 行索引 |
columns | 列索引 |
dtypes | 类型 |
size | 元素个数 |
ndim | 维度数 |
shape | 行列数目 |
DataFrame有两种访问方法,切片访问和索引名访问,这两种方法可以混用,如下:
# -*- coding: utf-8 -*-
import pandas as pd
data1 = {'a': [1, 2], 'b': [2, 3], 'c': [3, 4]}
df = pd.DataFrame(data1)
print(df['a'][0:1])
print(df[0:2])
print(df[0:2][0:1])
从上图可以很明显的看出,DataFrame的访问方式是列索引只能用索引名来访问,如果用切片访问只用于行索引,最后的df[0:2][0:1]和第一个df['a'][0:1]其实是对df进行了两次访问,这样的访问方法过于麻烦,所以常用loc和iloc函数进行访问操作(必考):
loc函数:DataFrame.loc[行索引名称或条件, 列索引名称]
例如实验一第三、四题:
iloc函数:DataFrame.iloc[行索引切片, 列索引切片]
可以很明显的看出来,loc的访问方式更加灵活,在机器学习里也更多使用loc来访问。(魔鬼细节:loc访问行索引的时候切片操作是前后均为闭区间,iloc是前闭后开)
还可以用head()和tail()函数来访问前几行和后几行数据:
例如实验一第二题:
还可以用loc函数来改变数据(这里的改动是对原始数据集进行改动,并不会生成新的数据集)
新加一列数据就比较简单了,直接写新增的列标签和对应数据就行:
删除某列或者某行数据用drop函数即可,drop一共有四个参数:
参数名称 | 说明 |
labels | 无默认值,可以接收数据对应下标或切片访问要删除的区域 |
axis | 默认是0,0代表删除行,1代表删除列 |
levels | 默认为None,不常用,代表标签所在级别 |
inplace | 默认为False,接收boolean,True代表对原始数据集进行删除,不创建新的数据集,False代表创建新的删除过后的数据集 |
、
pandas库基于numpy库,直接可以用numpy库里的函数进行描述性统计:
函数名称 | 说明 | 函数名称 | 说明 |
min | 最小值 | max | 最大值 |
mean | 均值 | ptp | 极差 |
median | 中位数 | std | 标准差 |
var | 方差 | cov | 协方差 |
sem | 标准误差 | mode | 众数 |
skew | 样本偏度 | kurt | 样本峰度 |
quantile | 四分位数 | count | 非空值数目 |
describe | 描述统计 | mad | 平均绝对离差 |
上述函数只能对某一行或一列(通常是列)进行计算,如下:
分组(groupby)和聚合(agg)函数
groupby函数用来给数据集进行分组,agg函数用来聚合,一般是分组在进行聚合操作,只进行分组不进行聚合操作无意义,聚合函数如果只要聚合一列直接用上述的描述性统计的函数即可,如果遇到多列要聚合建议用agg函数更为方便,例如实验一第五题:
其中groupby()函数里面的参数是要聚合的列标签,结尾加上[要聚合的列].sum()进行聚合操作,这里只要聚合一列便直接用sum即可,如果有多列要聚合可以在这样写:Data2.groupby(['fruit','month']).agg({‘第一个要聚合的列标签’: ‘要使用的函数’, ‘第二个要聚合的列标签’: ‘要使用的函数’……})
2.matplotlib可视化
机器学习的数据可视化操作基本上用matplotlib库可以实现,进行可视化操作往往是在结果评价那一步进行,只要掌握基础语法即可面对期末考试(若想学的仔细一点看最后一章扩展即可)。
这里只要掌握使用matplotlib库的pyplot类(下面简称plt)绘制五种常见的图形即可,分别是散点图、折线图、直方图、饼图、箱线图。下面是绘制图像的流程:
1.创建画布,确定图像所需的数据集(这里绘制的都是二维图像,只需要X数据和Y数据即可)
创建画布一般采用plt.figure(),在机器学习中一般不会的画布的大小进行限制,这里可以忽略这个画布设置。
而数据集在机器学习中一般是模型预测结果跑出来的数据,这里也不过多进行说明。
2.选择需要绘制的图形类型:
2.1折线图(重点)
在plt中折线图和曲线图等线型图均可用plt.plot(x,y)实现,实际绘制中不止可以填写x,y两个参数,还有以下参数可以填写:
参数名称 | 说明 |
x,y | 无默认值,接收数组,表示x轴和y轴的数据。 |
color | 默认为None,指定线条的颜色 |
linestyle | 默认为“-”,指定线条类型 |
marker | 默认为None,表示绘制的点的类型 |
alpha | 默认为None,表示点的透明度 |
其中,color参数常有以下八种:
参数值 | 代表的颜色 | 参数值 | 代表的颜色 |
b | 蓝色 | m | 品红 |
g | 绿色 | y | 黄色 |
r | 红色 | k | 黑色 |
c | 青色 | w | 白色 |
以下是个折线图的案例:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
y = [1, 2, 3, 4, 5, 6, 7, 8, 9]
y2 = [1, 4, 9, 16, 25, 36, 49, 64, 81]
# 绘制的曲线属性设置
plt.plot(x, y, color='r', marker='d', linestyle='--', markersize=6, alpha=0.5, linewidth=3)
plt.plot(x, y2, color='g', marker='*', linestyle='-', markersize=6, alpha=0.5, linewidth=3)
# plt.plot(x, y, 'rd--') # 可以使用这种方式进行画图的属性设置
# x,y坐标轴名称设置,可以同时设置标签的字体大小颜色等
plt.xlabel(u'x坐标轴', fontsize=14, color='r')
plt.ylabel(u'y坐标轴', fontsize=14, color='b')
# 显示曲线图像
plt.show()
2.2散点图(重点)
在plt中散点图可用plt.scatter(x,y)实现,实际绘制中不止可以填写x,y两个参数,还有以下参数可以填写:
参数名称 | 说明 |
x,y | 无默认值,接收数组,表示x轴和y轴的数据。 |
s | 默认为None,接收的是数值表示所有点的大小,接收数组表示各点的大小 |
c | 默认为None,接收的是颜色表示所有点的颜色,接收数组表示各点的颜色 |
marker | 默认为None,表示绘制点 的类型 |
alpha | 默认为None,表示点的透明度 |
以下是案例:
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
y = [1, 2, 3, 4, 5, 6, 7, 8, 9]
y2 = [1, 4, 9, 16, 25, 36, 49, 64, 81]
# 绘制的曲线属性设置
plt.scatter(x, y, c='red')
plt.scatter(x, y2, c='blue')
# plt.plot(x, y, 'rd--') # 可以使用这种方式进行画图的属性设置
# x,y坐标轴名称设置,可以同时设置标签的字体大小颜色等
plt.xlabel(u'x坐标轴', fontsize=14, color='r')
plt.ylabel(u'y坐标轴', fontsize=14, color='b')
# 显示曲线图像
plt.show()
2.3直方图
在plt中直方图可用plt.bar(x,y)实现,实际绘制中不止可以填写这些参数,还有以下参数可以填写:
参数名称 | 说明 |
x,y | 无默认值,接收数组,表示x轴和y轴的数据。 |
width | 默认为0.8,接收0-1之间的float,指定直方图宽度 |
color | 默认为None,接收的是颜色表示所有柱状的颜色,接收数组表示各柱状的颜色 |
以下是案例:
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
# 准备数据
xiaoming_score = [80, 75, 65, 58, 75, 80, 90] # 小明各科成绩
xiaohong_score = [90, 85, 75, 62, 75, 60, 80] # 小红各科成绩
subjects = ['语文', '英语', '数学', '物理', '化学', '生物', '体育']
plt.bar(x = np.arange(7), # 横坐标
height = xiaoming_score, # 柱状高度
width = 0.35, # 柱状宽度
label = '小明', # 标签
edgecolor = 'k', # 边框颜色
color = 'r', # 柱状图颜色
tick_label = subjects, # 每个柱状图的坐标标签
linewidth= 3) # 柱状图边框宽度
plt.legend() #显示标签
plt.show()
2.4饼图
在plt中直方图可用plt.pie(x)实现,实际绘制中不止可以填写这个参数,还有以下参数可以填写:
参数名称 | 说明 | 参数名称 | 说明 |
x | 无默认值,接收数组,表示用于绘制的数据 | autopct | 默认为None,指定数值的显示方式 |
explode | 默认为None,接收数组,表示指定项离饼图圆心为n个半径 | pctdistance | 默认为0.6,接收float,指定每一项的比例和距离饼图圆心n个半径 |
labels | 默认为None,接收字符串数组,指定每一项的名称 | labeldistance | 默认为1.1,接收float,指定每一项的名称和距离饼图圆心多少个半径 |
color | 默认为None,接收字符串数组,指定每一项的颜色 | radius | 默认为1,接收float,表示饼图的半径 |
以下是案例:
import matplotlib.pyplot as plt
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs' # 定义标签
sizes = [15, 30, 45, 10] # 每一块的比例
colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] # 每一块的颜色
explode = (0, 0.1, 0, 0) # 突出显示,这里仅仅突出显示第二块(即'Hogs')
plt.pie(sizes, explode=explode, labels=labels, colors=colors, autopct='%1.1f%%', shadow=True, startangle=90)
plt.axis('equal') # 显示为圆(避免比例压缩为椭圆)
plt.show()
2.5箱线图
在plt中直方图可用plt.boxplot(x)实现,实际绘制中不止可以填写这个参数,还有以下参数可以填写:
参数名称 | 说明 | 参数名称 | 说明 |
x | 无默认值,接收数组,表示用于绘制的数据 | positions | 默认为None,接收数组,表示图形位置 |
notch | 默认为False,接收boolean,表示中间箱体是否有缺口 | widths | 默认为None,接收数组,表示每个箱体的宽度 |
sym | 默认为None,接收字符串,指定异常点形状 | labels | 默认为None,接收数组,指定每一个箱线图的标签 |
vert | 默认为False,接收boolean表示图形是横向纵向或者横向 | meanline | 默认为False,表示是否显示均值线 |
以下是案例:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(100)
data = np.random.normal(size=(1000,4),loc=0,scale=1)
plt.boxplot(data)
plt.show()
3.添加画布内容(重点):
画布内容全靠函数进行改变添加,只需要记忆(根据英文意思记忆会非常快)对应函数就行,用法没有先后顺序,放在第二步和第四步结尾即可:
函数名称 | 函数作用 |
plt.title | 在当前plt创建的画布中添加标题,可以指定标题的名称、位置、颜色、字体大小等参数 |
plt.xlabel | 在当前plt创建的画布中添加x轴名称,可以指定位置、颜色、字体大小等参数 |
plt.ylabel | 在当前plt创建的画布中添加y轴名称,可以指定位置、颜色、字体大小等参数 |
plt.xlim | 指定当前plt创建的画布x轴的范围,只能确定一个数值区间,而无法使用字符串识别 |
plt.ylim | 指定当前plt创建的画布y轴的范围,只能确定一个数值区间,而无法使用字符串识别 |
plt.xticks | 指定x轴刻度的数目与取值 |
plt.yticks | 指定y轴刻度的数目与取值 |
plt.legend | 指定当前图形的图例,可以指定图例的大小、位置、标签 |
4.显示图像
在结尾加上plt.show()即可显示出上面绘制好的图形,整个绘图过程非常简单,简单记忆即可。
3.数据预处理
数据预处理过程是进行机器学习模型拟合的基础,数据处理的适当,结果的质量也能够提高,可以节约大量时间和空间,大部分的算法对于输入的数据也有要求,并且得到的数据集并不一定是我们所需要的数据集,加上可能会有很多的缺失值和噪声(错误值,也可以叫脏数据),在这一章只要记住几个名词的概念和一些简单的数据预处理方法即可:
3.1离散变量和连续变量:离散变量就是数据的取值不是连续的,可能是整数,也可能是字符串等,例如人的年龄,性别,爱好等;而连续变量则是数据的取值是连续的,例如人的身高、体重等。
3.2描述数据集中程度的度量:常见的有均值、中位数、众数、中列数等,其中中列数是最大值与最小值的均值。
3.3描述数据离散程度的度量:常见的有四分位数、四分位数极差、方差、极差等,其中极差是指测量之内最大值与最小值之差,极差越大,离散程度也越大,所以容易受极端值的影响;离散系数又称变异系数,数值是样本标准差与样本平均数的比值,离散系数越大,离散程度也越大。
3.4将数据集中不含缺失值的变量(属性)称为完全变量; 数据集中含有缺失值的变量称为不完全变量。
3.5数据中的某个或某些特征的值是不完整的,这些值称为缺失值。 pandas提供了识别缺失值的函数isnull()以及识别非缺失值的函数notnull(),这两种方法在使用时返回的都是布尔值True和False。 结合sum函数和isnull、notnull函数,可以检测数据中缺失值的分布以及数据中一共含有多少缺失值。 isnull和notnull之间结果正好相反,因此使用其中任意一个都可以判断出数据中缺失值的位置。
3.6对于缺失值有三种方法处理,第一是删除法:
删除法分为删除观测记录和删除特征两种,它属于利用减少样本量来换取信息完整度的一种方法,是一种最简单的缺失值处理方法。 pandas中提供了简便的删除缺失值的方法dropna,该方法既可以删除观测记录,亦可以删除特征。
DataFrame.dropna( axis=0, how='any', thresh=None, subset=None, inplace=False)
参数名称 | 说明 |
axis | 接收0或1。表示轴向,0为删除观测记录(行),1为删除特征(列)。 |
how | 接收特定string。表示删除的形式。any表示只要有缺失值存在就执行删除操作。all表示当且仅当全部为缺失值时执行删除操作。默认为any。 |
thresh | n,至少保留n个非nan行 |
subset | 接收类array数据。表示进行去重的列∕行。默认为None,表示所有列/行。 |
inplace | 接收boolean。表示是否在原表上进行操作。默认为False。 |
第二种就是替换法:
替换法是指用一个特定的值替换缺失值。 特征可分为数值型和类别型,两者出现缺失值时的处理方法也是不同的。 缺失值所在特征为数值型时,通常利用其均值、中位数和众数等描述其集中趋势的统计量来代替缺失值。 缺失值所在特征为类别型时,则选择使用众数来替换缺失值。
pandas库中提供了缺失值替换的方法名为fillna,其基本语法如下。
DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None)
参数名称 | 说明 |
value | 接收scalar,dict,Series或者DataFrame。表示用来替换缺失值的值。无默认。 |
method | 接收特定string。backfill或bfill表示使用下一个非缺失值填补缺失值。pad或ffill表示使用上一个非缺失值填补缺失值。默认为None。 |
axis | 接收0或1。表示轴向。默认为1。 |
inplace | 接收boolean。表示是否在原表上进行操作。默认为False。 |
limit | 接收int。表示填补缺失值个数上限,超过则不进行填补。默认为None。 |
第三种就是插值法(不重要):
删除法简单易行,但是会引起数据结构变动,样本减少;替换法使用难度较低,但是会影响数据的标准差,导致信息量变动。在面对数据缺失问题时,除了这两种方法之外,还有一种常用的方法—插值法。 常用的插值法有线性插值、多项式插值和样条插值等:
线性插值是一种较为简单的插值方法,它针对已知的值求出线性方程,通过求解线性方程得到缺失值。
多项式插值是利用已知的值拟合一个多项式,使得现有的数据满足这个多项式,再利用这个多项式求解缺失值,常见的多项式插值法有拉格朗日插值和牛顿插值等。
样条插值是以可变样条来作出一条经过一系列点的光滑曲线的插值方法,插值样条由一些多项式组成,每一个多项式都是由相邻两个数据点决定,这样可以保证两个相邻多项式及其导数在连接处连续。
3.7重复值处理:
重复值主要有记录重复和属性内容重复两种。 记录重复 利用集合set的特性去重 set(df['sex']) 但集合去重会导致数据排列的顺序发生改变。
pandas提供了一个名为drop_duplicates的去重方法。该方法只对DataFrame或者Series类型有效。该方法不仅支持单一特征的数据去重,还能够依据DataFrame的其中一个或者几个特征进行去重操作。
pandas.DataFrame(Series).drop_duplicates(self, subset=None, keep='first', inplace=False)
参数名称 | 说明 |
subset | 接收string或sequence。表示进行去重的列。默认为None,表示全部列。 |
keep | 接收特定string。表示重复时保留第几个数据。First:保留第一个。Last:保留最后一个。False:只要有重复都不保留。默认为first。 |
inplace | 接收boolean。表示是否在原表上进行操作。默认为False。 |
3.8数据标准化
在多指标评价体系中,由于各评价指标的性质不同,通常有不同的量纲和数量级。当各指标区间的水平相差很大时,如果直接使用原始数据,会突出数值较高的指标的作用,相对削弱数值水平较低指标的作用。
3.8.1最小-最大规范化
设原始数据为v,标准化后的数据为v’,max和min分别为这一列的最大值与最小值。公式如下:
对原始数据进行线性变换,将数值映射到[0,1]区间,当多个属性的数值分布区间相差较大时,使用最小-最大规范化,可以让这些属性值变换到同一个区间,这对于属性间的比较以及计算对象之间的距离很重要。
3.8.2零-均值标准化
将每一个属性的数据都减去这个属性的均值,变换后各属性的数据和与均值都为零。 S为原始数据的标准差。
将每一个属性的数据都减去这个属性的均值,变换后各属性的数据和与均值都为零。 多个属性经过零均值化变换后,都以零为均值分布,各属性的方差不发生变化,各属性间的协方差也不发生变化。 零均值化变换在很多场合得到应用,例如对信号数据零均值化,可以消除直流分量的干扰。在图像数据的预处理过程中,以及后面讲的主成分分析中也会用到。
3.9独热编码(重点):
对于类别性变量,例如性别、种类等的取值都是字符串,在机器学习模型拟合中要求的数据集取值尽量为数字,所以采用独热编码将字符型转化为对应的数字。在pandas库里也有对应的函数:
pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None)
参数名称 | 说明 |
data | 原始数据集 |
prefix | 给输出的列添加前缀,如prefix="A",输出的列会显示类似 |
prefix_sep | 设置前缀跟分类的分隔符sepration,默认是下划线"_" |
例如实验三:
4.机器学习经典算法——回归、分类、聚类
接下来开始正式进入机器学习模型拟合,机器学习顾名思义就是让机器学会学习,进行人为指导的任务,根据数据集是否提供标签可以将机器学习模型分为有监督学习、半监督学习、无监督学习。有监督学习的意思就是数据集中全部数据都有一列标签,这个标签也是机器学习进行拟合求出的结果,有监督学习常见模型有线性回归等预测类模型和贝叶斯分类、决策树分类等分类模型。半监督学习就是有部分标签的数据集,用的很少,复习时可以忽略。无监督学习就是没有标签的数据集,常见的有K-means聚类等。
预测问题——线性回归
本文针对复习,简单说明算法目的,不对算法原理进行讲解,有需求的可以自行搜集学习原理。
线性回归有一元线性回归和多元线性回归,一元线性回归就是一个自变量(X)求一个结果(Y),多元线性回归就是多个自变量(X)求一个结果(Y),要求数据集除了标签列,每一列都是不同特征对应的取值,取值要求是数字型,标签列就是我们要求的结果,我们训练模型的目的就是为了根据我们给出的数据集拟合出一个一元(或多元)函数,然后当我们输入特征(自变量X),模型会给出对应结果。
分类问题——逻辑回归
逻辑回归原理和线性回归很像,只不过要求的结果不同,逻辑回归是用来进行二分类问题的(例如标签不是1就是2),线性回归输出的结果是离散型数字,而逻辑回归输出的结果是分类结果,其他的原理和线性回归一样。
分类问题——决策树分类
决策树的原理就是根据输入的特征(自变量X)来构造树进行二分类(或多分类)问题,输出的结果格式和逻辑回归一样。下面是一个决策树的例子:
分类问题——KNN分类
KNN的原理非常简单,为了判断未知样本的类别,以所有已知类别的样本(训练的数据集)作为参照,计算未知样本(输入的要预测的数据集)与所有已知样本(训练的数据集)的距离,从中选取与未知样本距离最近的K个已知样本,根据少数服从多数的投票法则,将未知样本与K个最邻近样本中所属类别占比较多的归为一类。这里的距离算法有很多种,例如欧氏距离、余弦距离、汉明距离、曼哈顿距离等,常用欧氏距离。
分类问题——贝叶斯分类
朴素贝叶斯分类基于贝叶斯公式,可以处理多分类问题,是一种通过根据新样本的已有特征在数据集中的条件概率(后验概率)来判断新样本所属类别的算法,其将样本判定为后验概率最大的类。
之所以称之为“朴素”,因为它假设:
① 每个特征之间相互独立
② 每个特征同等重要。
贝叶斯定理
在 B 出现的前提下 A 出现的概率,等于 A 和 B 都出现的概率除以 B 出现的概率。
我们希望确定一个具有某些特征的样本属于某类标签的概率,通常记为 P (L |特征 )。贝叶斯定理告诉我们,可以直接用下面的公式计算这个概率:
(L 为某个标签)
聚类问题——K-means聚类
聚类问题都是无监督学习,所以给出的数据集每一行没有对应的标签,我们的任务就是将这些没有标签的数据分类,给出分类结果的标签,K-means聚类就是常见的聚类模型。
K-Means聚类算法步骤实质是EM算法(最大期望算法(Expectation-Maximization algorithm, EM))的模型优化过程,具体步骤如下:
(1)随机选择k个样本作为初始簇类的均值向量;
(2)将每个样本数据集划分离它距离最近的簇;
(3)根据每个样本所属的簇,更新簇类的均值向量;
(4)重复(2)(3)步,当达到设置的迭代次数或簇类的均值向量不再改变时,模型构建完成,输出聚类算法结果。
机器学习进行训练模型的具体步骤:
上述的模型拟合在机器学习库sklearn库里面都可以总结成五部分,这里记忆就行:
第一步:导入对应库(期末考试会给出对应库,不用记忆,理解就行)
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split ## 划分数据集的库
from sklearn.linear_model import LinearRegression ## 线性回归库
from sklearn.linear_model import LogisticRegression ## 逻辑回归库
from sklearn.tree import DecisionTreeClassifier ## 决策树库
from sklearn.neighbors import KNeighborsClassifier ## KNN库
from sklearn.naive_bayes import GaussianNB ## 贝叶斯库
from sklearn.cluster import KMeans ## K-means库
第二步:导入数据集
# 导入数据集
data = pd.read_csv('') ##引号内填对应路径
第三步:数据分割与数据预处理
# 如果要进行数据预处理在分割数据集之前
###
这里填要预处理的部分
###
# 分割X,y
X = data.drop('', axis=1)
y = data['']
# 分割训练集,测试集(训练集用来拟合数据,测试集用来评估模型结果,一般分割比是测试集占0.2)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
第四步:选择模型,训练模型
# 线性回归
model = LinearRegression()
# 逻辑回归
model = LogisticRegression()
# 决策树分类
model = DecisionTreeClassifier()
# KNN
model = KNeighborsClassifier(n_neighbors=3) # n_neighbors: int, k值,可选参数(默认为 5)
# 高斯朴素贝叶斯
model = GaussianNB()
# KMeans
model = KMeans(n_clusters=3) # n_clusters:int,要聚类的类别总数
model.fit(X_train, y_train)
第五步:预测结果
y_pred = model.predict(X_test) # 这里的X_test选择你想预测的特征集,y_pred就是预测的结果
结合如下:
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split ## 划分数据集的库
from sklearn.linear_model import LinearRegression ## 线性回归库
from sklearn.linear_model import LogisticRegression ## 逻辑回归库
from sklearn.tree import DecisionTreeClassifier ## 决策树库
from sklearn.neighbors import KNeighborsClassifier ## KNN库
from sklearn.naive_bayes import GaussianNB ## 贝叶斯库
from sklearn.cluster import KMeans ## K-means库
# 导入数据集
data = pd.read_csv('')
# 分割X,y
X = data.drop('', axis=1)
y = data['']
# 分割训练集,测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练模型(选择合适的模型留下一个即可)
# 线性回归
model = LinearRegression()
# 逻辑回归
# model = LogisticRegression()
# 决策树分类
# model = DecisionTreeClassifier()
# KNN
# model = KNeighborsClassifier(n_clusters=3)
# 高斯朴素贝叶斯
# model = GaussianNB()
# KMeans
# model = KMeans(n_clusters=3)
model.fit(X_train, y_train)
# 输出结果
y_pred = model.predict(X_test)
简单吧,机器学习在前辈们的努力下集成到sklearn库里已经是非常成熟的算法库了,现在机器学习模型越来越成熟的情况下建议友友们去深度学习领域去钻研更容易找到出路,深度学习也是机器学习的一个分支,属于比较难的深度学习了。
接下来看最后一节课给出的例题(重点):
1.现有特征数据:[[1,1],[2,2],[2,4],[3,6]],设置合理的类别数目,运用KMeans算法完成聚类(提示:建模可能使用的模块为from sklearn.cluster import KMeans)。
# -*- coding: utf-8 -*-
from sklearn.cluster import KMeans
import numpy as np
data = np.array([[1, 1], [2, 2], [2, 4], [3, 6]])
kmeans = KMeans(n_clusters=2)
kmeans.fit(data)
labels = kmeans.labels_
print(labels)
结果:
这个结果是个列表,内容就是每一行特征对于的聚类结果。
2.目前有房屋面积和租金价格如下:房屋面积10平方,房间数量为1,租金为800元;房屋面积20平方,房间数量为1,租金为1千元;房屋面积30平方,房间数量为2,租金为1.2千元;房屋面积50平方,房间数量为2,租金为2千元。请使用线性回归算法预测,一个房屋面积为55平方,房间数量为1的房屋,租金多少比较合适?(提示:建模可能使用的模块为from sklearn.linear_model import LinearRegression)。
# -*- coding: utf-8 -*-
from sklearn.linear_model import LinearRegression
X_train = [[10,1],[20,1],[30,2],[50,2]]
Y_train = [0.8,1,1.2,2]
X_test = [[55,1]]
model=LinearRegression()
model.fit(X_train, Y_train)
res = model.predict(X_test)
print(res)
5.机器学习的结果评价
对于机器学习的结果,不同的模型有不同的评价方式,对于期末考试而言,只需要掌握以下几种评价方式即可。
对于分类问题,常用以下方法:
混淆矩阵
如上混淆矩阵所示,引出以下概念:
TP、TN、FP、FN中第一个字母(行标首字母)是根据真实情况判断预测结果是否正确。(正确:T、错误:F) TP、TN、FP、FN中第二个字母(列标首字母)是预测的结果。(正例:P,反例:N)
TP:正确的预测为正例。 FP:错误的预测为正例。 TN:正确的预测为反例。 FN:错误的预测为反例。
(重点)
准确率:总样本中预测对了多少 (TP+TN)/(TP+TN+FP+FN)
精确率(差准率):预测为正的样本中,实际为正的有多少 TP/(TP+FP)
召回率(查全率、recall):实际为正的样本中有多少被预测为正了 TP/(TP+FN)
F1=2(精确率*召回率)/精确率+召回率 实际就是精确率和召回率的调和平均值(F1:为了让一个评价指标里,既能体现查准率又能体现召回率而编的。)
ROC曲线的横坐标为FPR,纵坐标为TPR TPR(真正率),也叫灵敏度,是正确的预测为正的概率。 TPR=TP/(TP+FN)=TP/P FPR(假正率),也叫特异度,是错误的预测为正的概率。 FPR=TN/(FP+TN)=TN/N
AUC表示ROC曲线下方的面积
AUC是1乘1的方格中的一部分,其大小在0-1之间
AUC=1,是完美的分类器,该模型至少存在一个阈值,可以讲正负样本完美的分开。 0.5<AUC<1,优于随机猜测,数值越大,分类器越好
AUC=0.5,相当于随机猜测,模型没有预测价值
AUC<0.5,比随机猜测要差,然而若反向预测,该模型也可优于随机猜测
代码如下:
from sklearn.metrics import accuracy_score, precision_score, recall_score, roc_curve, auc
###
这部分放前面机器学习拟合过程
###
y_pred = model.predict(X_test)
# 打印模型评估分数
score = model.score(X_test, y_test)
Accuracy = accuracy_score(y_test, y_pred)
Precision = precision_score(y_test, y_pred, average='macro')
Recall = recall_score(y_test, y_pred, average='macro')
print("准确率:", score)
print("分类器的准确率:{}".format(Accuracy))
print("分类器的精确率:{}".format(Precision))
print("分类器的召回率:{}".format(Recall))
对于回归问题,常用以下方法:
分类问题的评价指标是准确率,那么回归算法的评价指标就是MSE,RMSE,MAE、R-Squared。
均方误差(MSE):
均方根误差(RMSE):
平均绝对误差(MAE):
R决定系数
总平方和
残差平方和
yi表示真实数据 fi表示预测数据
代码如下:
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
###
这里放模型拟合过程
###
# 输出误差
# MSE
mse = mean_squared_error(y_test, y_pred)
print("MSE:", mse)
# RMSE
rmse = np.sqrt(mse)
print("RMSE:", rmse)
# MAE
mae = mean_absolute_error(y_test, y_pred)
print("MAE:", mae)
# R2
r2 = r2_score(y_test, y_pred)
print('R2分数:', r2)