数据和特征决定了机器学习的上限,而算法和模型只是逼近了这个上限而已
特征工程就是运用知识和技巧处理数据,使特征能在机器学习算法上发挥更好作用的过程
特征提取
将任意格式的数据转化为可用于机器学习的数据。文本文件->csv
特征预处理
通过一些转化函数将一些数据转化为一定范围内的数据,eg:都变为(0,1)之间的数
特征降维
标称型目标变量的结果只有在有限目标集中取值,{真,假},{鱼类,狗类,猫类}。通常分类算法的目标变量(y)为标称型
数值型目标变量从无限的数据集中取值。通常回归算法的y为数值型
每个实例(训练样本)都有好多特征(也可叫做属性)。目标变量(y,类别)。
假定这个鸟类分类程序,经过测试满足精确度要求,是否我们就可以看到机器巳经学会了如 何区分不同的鸟类了呢?这部分工作称之为知识表示,某些算法可以产生很容易理解的知识表 示,而某些算法的知识表示也许只能为计算机所理解。知识表示可以采用规则集的形式,也可以 采用概率分布的形式,设置可以是训练样本集中的一个实例。在某些场合中,人们可能并不想建 立一个专家系统,而仅仅对机器学习算法获取的信息感兴趣。此时,采用何种方式表示知识就显 得非常重要了。
将数据集合分成由类似对象组成的多个类的过程
寻找描述数据统计值的过程
Numpy的核心数据结构是array数组,array比list优点在于性能好,包含数组元数据信息,大量的便捷函数且array的元素必须是同一个数据类型
#创建array使用第一种
>>> import numpy as np
>>> x=np.array([1,2,3,4]) #一维数组
>>> x
array([1, 2, 3, 4])
>>> X=np.array([[1,2,3],[4,5,6]])
>>> X #二维数组
array([[1, 2, 3],
[4, 5, 6]])
#探索array的属性
>>> x.shape
(4,)
>>> X.shape
(2, 3)
>>> x.ndim
1
>>> X.ndim
2
>>> x.size
4
>>> X.size
6
>>> x.dtype
dtype('int32')
>>> X.dtype
dtype('int32')
#创建array的第二种方法
(1)arange([start,]stop[,step],dtype=None)
>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(2,10,2) #2到10 步长2
array([2, 4, 6, 8])
(2)ones(shape,dtype=None,order='C')创建都为1的数组,#看第一个shape传入一个元组
>>> np.ones(10)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
>>> np.ones((2,3))
array([[1., 1., 1.],
[1., 1., 1.]])
ones_like()(a,dtype=float,order='C')#看第一个 a 传入一个其他的array,创建同样形状的array
>>> np.ones_like(x)
array([1, 1, 1, 1])
(3)zeros,zeros_like(都为0)
(4)np.empty(shape,dtype=float,order='C')#数据是未经初始化的,里面的值可能是随机值不要用 empty_like()
>>> np.empty(5)
array([6.23042070e-307, 7.56587584e-307, 1.55762979e-307, 1.11260483e-306,
2.75083780e+199])
(5)np.full(shape,fill_value,dtype=None,order='C'), full_like()#fill_value是填充的数字
>>> np.full(5,666)
array([666, 666, 666, 666, 666])
>>> np.full((2,2),22)
array([[22, 22],
[22, 22]])
#第三种方法生成array
>>> np.random.randn()
-1.6596641138392463
>>> np.random.rand(1,2)
array([[0.45781965, 0.05185864]])
>>> np.random.rand(3,2,1)
array([[[0.16439023],
[0.75147253]],
[[0.46252664],
[0.5536307 ]],
[[0.8682315 ],
[0.15362499]]])
>>> np.random.randint(1,100,10)
array([65, 49, 20, 24, 35, 30, 24, 37, 33, 81])#开始1 结束100 生成10个随机整数
#arr.argsort()会返回排序后的索引index
>>> a.argsort()
array([2, 3, 6, 5, 8, 4, 7, 1, 0, 9], dtype=int64)
#找出最大的三个值
a.argsort()[-3,] #啥玩意!先不看了
#布尔索引
>>> x=np.arange(10)
>>> x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> x>5
array([False, False, False, False, False, False, True, True, True, True])
>>> x[x>5]
array([6, 7, 8, 9])
#组合条件索引
>>> c=(x%2==0)|(x>7)
>>> x[c]
array([0, 2, 4, 6, 8, 9])
>>> b=(x%2==0)&(x>7)
>>> x[b]
array([8])
>>> a=np.arange(10).reshape(2,5)
>>> a
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
a.argmin()#返回最小处的索引
>>> a.shape
(2, 5)
>>> a.ndim
2
>>> a+1
array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10]])
>>> a*3
array([[ 0, 3, 6, 9, 12],
[15, 18, 21, 24, 27]])
>>> np.sin(a)
array([[ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 ],
[-0.95892427, -0.2794155 , 0.6569866 , 0.98935825, 0.41211849]])
>>> np.exp(a)
array([[1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
5.45981500e+01],
[1.48413159e+02, 4.03428793e+02, 1.09663316e+03, 2.98095799e+03,
8.10308393e+03]])
>>> c=np.arange(10).reshape(2,5)
>>> c
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> c[1,2] #二维数组索引c[1][2]也可
7
>>> c[:,2] #所有行,2列
array([2, 7])
>>> c[:,2]=666
>>> c
array([[ 0, 1, 666, 3, 4],
[ 5, 6, 666, 8, 9]])#numpy的切片修改会改变原数组,因为numpy处理的是大数组,为了避免复制就这样了
>>> a+c
array([[ 0, 2, 4, 6, 8],
[10, 12, 14, 16, 18]])
>>> a-c
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
np.dot(a,b)#点乘运算
a@b #矩阵乘法,相当于np.matmul()函数
np.log(a) np.power(a,2) np.sqrt(a) #对数,指数,平方根运算
>>> from numpy import*
>>> random.rand(4,4) #构造随机数组
array([[0.74878853, 0.52560907, 0.22699431, 0.95620713],
[0.82337348, 0.82362872, 0.5959739 , 0.4568728 ],
[0.96239032, 0.67604826, 0.65252506, 0.31628161],
[0.81762286, 0.99090677, 0.05270264, 0.8578375 ]])
>>> ranMat=mat(random.rand(4,4)) #将数组转为矩阵
>>> ranMat
matrix([[0.99251935, 0.82413452, 0.30488729, 0.82584834],
[0.23885602, 0.60325735, 0.84851859, 0.5168431 ],
[0.1295934 , 0.83457051, 0.98254559, 0.93423105],
[0.39215636, 0.16447036, 0.47680987, 0.3539198 ]])
>>> invRandMat=ranMat.I #.I求逆运算
>>> invRandMat #invertor反,倒置
matrix([[ 0.59398022, 0.74386018, -1.32769107, 1.03236284],
[ 0.8475697 , 2.77421016, -0.95018538, -3.52086184],
[-0.71902239, 1.58377899, -0.64533197, 1.06839848],
[-0.0833416 , -4.24713824, 2.78210061, 1.87841095]])
>>> ranMat*invRandMat#矩阵乘法,主对角元都为1,其他都为0,是 E
matrix([[ 1.00000000e+00, 0.00000000e+00, 0.00000000e+00,-2.22044605e-16],
[-1.11022302e-16, 1.00000000e+00, 1.11022302e-16,2.22044605e-16],
[-1.11022302e-16, -4.44089210e-16, 1.00000000e+00,4.44089210e-16],
[ 2.77555756e-17, -2.22044605e-16, 0.00000000e+00,1.00000000e+00]])
ranMat*invRandMat-eye(4)得到误差值 eye(4)是单位矩阵
>>> np.random.random(5)
array([0.32569065, 0.88889931, 0.62640453, 0.81887369, 0.54734542])
>>> np.random.random(size=(3,4))
array([[0.41671201, 0.74304719, 0.36959638, 0.07516654],
[0.77519298, 0.21940924, 0.07934213, 0.48678052],
[0.1536739 , 0.82846513, 0.19136857, 0.27040895]])
>>> np.random.random()
0.5610344211351077
>>> np.random.choice(5,(2,3))
array([[0, 3, 3],
[1, 1, 4]])
>>> np.random.choice([2,3,4,5],(2,3))
array([[2, 2, 4],
[3, 4, 3]])
>>> a=np.arange(10)
>>> np.random.shuffle(a)
>>> a #本身进行了打散
array([6, 7, 5, 8, 0, 2, 3, 1, 9, 4])
#打散二维数组时时候打散第一维度
给定一个有标签的训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的
多数属于某个类,就把该输入实例分类到这个类中。
采用测量不同特征值之间的距离方法进行分类
k太小,极限的想,k=1,(他的类别就是离他最近的)忽略数据的真实分布,过拟合
k太大,极限的想,k=训练样本个数,不是加权平均时,数k个样本中,哪个类别数量最多,结果就为哪个类别,明显错误,这时与输入实例较远的(不相似)训练实例也会对预测起作用
我们一般选取一个较小的数值,通常采取 交叉验证法来选取最优的k值。(也就是说,选取k值很重要的关键是实验调参,类似于神经网络选取多少层这种,通过调整超参数来得到一个较好的结果)
每一个特征写作每一个维度,作为坐标上的一个轴,用欧式公式计算距离时,很容易受值很大的维度的影响,造成特征不是等价重要。
为了让每个特征值同等重要,就要特征归一化
方法:计算每一个轴的最大值最小值之差(Mi),计算距离时,每一个坐标轴-最小值除以相应的Mi(100等级的x轴,1等级的y轴,x轴经过特征归一化变为1等级)
计算加权平均:距离近的占权重大
def autoNorm(dataSet):
# 每一列最小值
minVals = dataSet.min(0)
# 每一列最大值
maxVals = dataSet.max(0)
# 每一列的差
ranges = maxVals - minVals
# 复制矩阵 dataSet的行,列。值都是0
normDataSet = zeros(shape(dataSet))
# 得到多少行
m = dataSet.shape[0]
# tile(minVals, (m,1)) 创建datSet的行列的矩阵,每一个值都是minVals。
# dataSet - 矩阵相减
normDataSet = dataSet - tile(minVals, (m,1))
# tile(ranges, (m,1)) 创建datSet的行列的矩阵,每一个值都是ranges。
# 并非矩阵除法,而是对应位置的值相除
normDataSet = normDataSet / tile(ranges, (m,1))
return normDataSet, ranges, minVals
训练样本集都有标签,即样本集中每个数据属于哪个分类。输入测试样本后,新数据每个特征与样本集中对应特征进行比较,然后算法提取样本集中特征最相似数据的分类标签。我们只选择样本数据集中前k个最相似的数据,k个最相似数据中出现次数最多的分类作为新数据的分类。
#训练数据存放在文本文件中时
def file2matrix(filename):
#打开文件
fr = open(filename)
#以列表的格式返回全部文本,文本的第几行对应列表的第几个元素
arrayOLines = fr.readlines()
#文件行数
numberOfLines = len(arrayOLines)
#创建以0填充的矩阵
returnMat = zeros((numberOfLines,3))
classLabelVector = []
index = 0
#循环数据每行
for line in arrayOLines
#截掉所有回车符
line = line.strip()
#将每行分割
listFromLine = line.split('\t1')
#存储特征矩阵
returnMat[index:,:] = listFromLine[0:3]
#存储标签向量中
classLabelVector.append(int(listFromLine[-1]))
index += 1
return returnMat,classLabelVector
举个例子:根据电影之中的打斗镜头与接吻镜头数判断电影类别
(我们通常只能可视化处理三维以下的事物,为了简单的实现数据可视化,每个数据点使用两个特征)
C:\Users\HUAWEI>e:
E:\>cd E:\python代码\machineLearning
E:\python代码\machineLearning>python
Python 3.8.5 (default, Sep 3 2020, 21:29:08) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import kNN
>>> group,lables=kNN.createDataSet()
>>> group
array([[1. , 1.1],
[1. , 1. ],
[0. , 0. ],
[1. , 0.1]])
>>> lables
['A', 'A', 'B', 'B']
>>> kNN.classify0([0,0],group,lables,3)
‘B’
Traceback (most recent call last):
File "" , line 1, in <module>
File "E:\python代码\machineLearning\kNN.py", line 49, in classify0
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
AttributeError: 'dict' object has no attribute 'iteritems'
解决:该错误出现的原因是python版本的变化,python2.X不会报错,而Python3.X会报错,因为Python3.X中去除了iteritems(),将iteritems()替换为items()
对未知类别属性的数据集中的每个点依次执行以下操作:
一个目的:构造回归方程(regression equation)
待续…