机器学习基础知识,numpy学习,分类和回归初识

内容

  • 机器学习基本知识
      • 特征工程
        • 特征工程内容
      • 监督学习一般使用标称型和数值型两种目标变量
      • 知识表示
      • 聚类
      • 密度估计
      • 思路
  • numpy的使用
      • array对象
        • array对象的属性
        • 创建array的方法
        • 代码演示
        • array本身支持的操作
        • random
  • 分类
    • k邻近算法-KNN
      • 概述:
      • k的选取
      • 特征归一化的必要性
      • 优点:缺点:
      • 工作原理:
      • 一般流程
      • 伪代码
  • 回归
    • 线性回归
      • 一般流程

机器学习基本知识

数据和特征决定了机器学习的上限,而算法和模型只是逼近了这个上限而已

特征工程

特征工程就是运用知识和技巧处理数据,使特征能在机器学习算法上发挥更好作用的过程

特征工程内容
  • 特征提取

    将任意格式的数据转化为可用于机器学习的数据。文本文件->csv

  • 特征预处理

    通过一些转化函数将一些数据转化为一定范围内的数据,eg:都变为(0,1)之间的数

  • 特征降维

监督学习一般使用标称型和数值型两种目标变量

标称型目标变量的结果只有在有限目标集中取值,{真,假},{鱼类,狗类,猫类}。通常分类算法的目标变量(y)为标称型

数值型目标变量从无限的数据集中取值。通常回归算法的y为数值型

每个实例(训练样本)都有好多特征(也可叫做属性)。目标变量(y,类别)。

知识表示

假定这个鸟类分类程序,经过测试满足精确度要求,是否我们就可以看到机器巳经学会了如 何区分不同的鸟类了呢?这部分工作称之为知识表示,某些算法可以产生很容易理解的知识表 示,而某些算法的知识表示也许只能为计算机所理解。知识表示可以采用规则集的形式,也可以 采用概率分布的形式,设置可以是训练样本集中的一个实例。在某些场合中,人们可能并不想建 立一个专家系统,而仅仅对机器学习算法获取的信息感兴趣。此时,采用何种方式表示知识就显 得非常重要了。

聚类

将数据集合分成由类似对象组成的多个类的过程

密度估计

寻找描述数据统计值的过程

思路

  1. 首先考虑使用机器学习算法的目的。如果想要预测目标变量的值,则可以选择监督学习算法, 否则可以选择无监督学习算法。
  2. 确定选择监督学习算法之后,需要进一步确定目标变量类型,如 果目标变量是离散型,如是/否、1/2/3、― 冗或者红/黄/黑等,则可以选择分类器算法;如果目标变量是连续型的数值,如0.0~ 100.00、-999999或者+00-00等 ,则需要选择回归算法。
  3. 如果不想预测目标变量的值,则可以选择无监督学习算法。进一步分析是否需要将数据划分 为离散的组。如果这是唯一的需求,则使用聚类算法;如果还需要估计数据与每个分组的相似程 度 ,则需要使用密度估计算法。

numpy的使用

array对象

Numpy的核心数据结构是array数组,array比list优点在于性能好,包含数组元数据信息,大量的便捷函数且array的元素必须是同一个数据类型

array对象的属性
  • shape:返回一个元组,表示array的维度
  • ndim:返回一个数字,表示维度 #numbei dimension
  • size:返回一个数字,表示所有元素的个数
  • dtype:数据类型 #data type
创建array的方法
  • 从python的列表和嵌套列表创建array
  • 使用预定义函数
  • 生成随机数的np.random模块创建
代码演示
#创建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])
array本身支持的操作
>>> 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)是单位矩阵
random
  • seed 设置随机种子,使每次生成的随机数一样
  • rand() [0,1)之间具有均匀分布的数据
  • randn() 返回数据具有标准正态分布 均值0方差1
  • normal( [loc,scale,size] ) 按照平均值loc,方差scale生成高斯分布的数字
  • uniform( [low,high,size] ) 在[low,high)之间生成均匀分布的数字,或者[0,low) size使用元组可以决定数组类型
  • randint ( low [,high,size,dtype] ) 生成随机整数
  • random([size]) [0.0,1.0)之间的随机数
>>> 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
  • choice(a [,size,replace,p] ) a是一维数组,从它里面生成随机结果,a是数字时,选0~a之间的随机整数。从前面选数字,以后面格式放入
>>> 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]])
  • shuffle(x) 把数组x随机排序
>>> a=np.arange(10)
>>> np.random.shuffle(a)
>>> a             #本身进行了打散
array([6, 7, 5, 8, 0, 2, 3, 1, 9, 4])
#打散二维数组时时候打散第一维度
  • permutation(x) 把数组x随机排序,或数字全排列 #本身不进行打散,返回新的copy

分类

k邻近算法-KNN

概述:

给定一个有标签的训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这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个最相似数据中出现次数最多的分类作为新数据的分类。

一般流程

  1. 收集数据:使用任何方法导入数据
  2. 准备数据:用结构化数据格式,距离计算所需要的数值。
  3. 分析数据:各种方法
  4. 训练算法:这个步骤不适合k-邻近算法
  5. 测试算法:计算错误率
  6. 使用算法:输入样本数据和结构化的输出结果,用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()

伪代码

对未知类别属性的数据集中的每个点依次执行以下操作:

  1. 计算已知类别数据集中的点与当前点之间的距离;
  2. 按照距离递增次序排序;
  3. 选取与当前点距离最小的k个点;
  4. 确定前k个点所在类别的出现频率;
  5. 返回前k个点出现频率最高的类别作为当前点的预测分类。

回归

线性回归

一个目的:构造回归方程(regression equation)

一般流程

  1. 收集数据:使用任何方法导入数据
  2. 准备数据:回归需要数值型数据,标称型数据被转成二次型
  3. 分析数据:绘出数据的可视化二维图将有助于对数据做出理解和分析,在采用缩进法求得新回归系数后,可以将新拟合线绘在图上作为对比。
  4. 训练算法:找到回归系数
  5. 测试算法:使用R2或者预测值和数据的拟合度,来分析模型的结果
  6. 使用算法:使用回归,给定输入后预测出一个数值,是对分类方法的提升(因为这样可以预测连续型数值而不仅仅是离散的类别标签)

待续…

你可能感兴趣的:(笔记,机器学习,回归,分类,python,numpy)