欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

机器学习实战第二章

程序员文章站 2022-03-22 23:00:58
...
K邻近算法:
优点:精度高,对异常值不敏感、无数据输入假定

缺点:计算复杂度高、空间复杂度高

使用数据范围:数值型和标称型

一、KNN算法例子

'''
这是一个KNN练习的模块
(1)计算已知类别数据集中的点与当前点的距离
(2)按照距离递增次序排序
(3)选取与当前点距离最小的K个点
(4)确定前K个点所在类别的出现频率
(5)返回前K个点出现频率最高的类别作为当前点的预测分支
'''
import  numpy as np     #科学计算包
import  operator as op  #运算符包

#创建的分类函数
def createDataSet():
    group = np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels = ['A','A','B','B']
    return group,labels

'''
X:用于分类的输入向量
dataSet:输入的训练样本集
labels:标签向量(其中标签向量的元素数据和矩阵dataSet的行数相同)
k:用于选择临近的数目
使用的是欧式距离公式
'''
def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]  #shape返回的是行和列
    print(dataSet.shape)
    diffMat = np.tile(inX, (dataSetSize,1)) - dataSet  #tile变为和怎么个矩阵,然后做减法操作
    print(diffMat)
    sqDiffMat = diffMat**2 #平方操作
    print(sqDiffMat)
    sqDistances = sqDiffMat.sum(axis=1) #没有axis参数表示全部相加,axis=0表示按列相加,axis=1表示按照行的方向相加
    print(sqDistances)
    distances = sqDistances**0.5 #开方操作
    sortedDistIndicies = distances.argsort() #排序返回的是索引
    print(sortedDistIndicies)
    classCount={} #相当于一个MAP
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #get(key,default) 字典获取值 没有返回默认值
        print(classCount)
    sortedClassCount = sorted(classCount.items(), key=op.itemgetter(1), reverse=True)#key是个比较函数,reverse是递增或者递减
    print(sortedClassCount)
    return sortedClassCount[0][0]

import com.knn.kNN as kNN
group,labels=kNN.createDataSet()
print(group)
print(labels)
print(kNN.classify0([10,0],group,labels,3))

二、这部分用到的数学知识

机器学习实战第二章机器学习实战第二章

三、函数说明

np.tile

>>> tile(1.3,2)
array([ 1.3,  1.3])
array([1, 2, 1, 2, 1, 2])
>>> tile((1,2,3),2)
array([1, 2, 3, 1, 2, 3])
>>> a=[[1,2,3],[4,5,5]]
>>> tile(a,2)
array([[1, 2, 3, 1, 2, 3],
       [4, 5, 5, 4, 5, 5]])
>>> tile([1,2,3],[2,2,2,2])

二、后续

def file2matrix(filename):
    fr = open(filename)                          #打开一个文件
    numberOfLines = len(fr.readlines()) #得到文件的行长度
    returnMat = zeros((numberOfLines,3))   #得到一个二维数组 第一个参数是行数,第二个参数每个数组的个数
    classLabelVector = []                       #prepare labels return   
    fr = open(filename)
    index = 0
    for line in fr.readlines():
        line = line.strip()
        listFromLine = line.split('\t')
        returnMat[index,:] = listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index += 1
    return returnMat,classLabelVector
from numpy import *
import kNN
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure() #创建图表

'''
add_subplot(mnp)添加子轴、图。
subplot(m,n,p)或者subplot(mnp)此函数最常用:subplot是将多个图画到一个平面上的工具。
其中,m表示是图排成m行,n表示图排成n列,
也就是整个figure中有n个图是排成一行的,一共m行,如果第一个数字是2就是表示2行图。
p是指你现在要把曲线画到figure中哪个图上,最后一个如果是1表示是从左到右第一个位置。  
'''

ax = fig.add_subplot(111)#在图表1中创建子图1
datingDataMat,datingLabels = kNN.file2matrix('datingTestSet.txt')
#ax.scatter(datingDataMat[:,1], datingDataMat[:,2])#用第二列的数据作为X轴,第三列的数据作为Y轴 后面了两个换算出来会是大小和颜色
ax.scatter(datingDataMat[:,1], datingDataMat[:,2], 15.0*array(datingLabels), 15.0*array(datingLabels))
ax.axis([-2,25,-0.2,2.0])#X轴范围,Y轴范围
plt.xlabel('Percentage of Time Spent Playing Video Games')
plt.ylabel('Liters of Ice Cream Consumed Per Week')
plt.show()

效果图 机器学习实战第二章

三、数值归一处理的原因

有很多数据的特征值不止一个,特征值中有些属性的数字过大,从而对计算结果的影响太大,但是实际情况是每个属性都同等重要,这时候就要处理这种不同取值范围的特征值,通常采用数值归一化,将取值范围处理为0-1或者-1-1之间。
将任意取值范围的特征值转化为0–1区间内的值,公式如下:

newValue=(oldValue-min)/(max-min)

    1

其中oldValue为原始数据
min、max分别是原始数据里最小、最大值
例如:有一组数据如下
400
134000
20000
32000
归一化的过程是:
400归一化之后的值newValue=(400-400)/(134000-400)
134000归一化之后的值newValue=(134000-400)/(134000-400)
20000归一化之后的值newValue=(20000-400)/(134000-400)
32000归一化之后的值newValue=(32000-400)/(134000-400) 

四、数据归一

'''
数值归一化处理
'''
def autoNorm(dataSet):
    minVals = dataSet.min(0)    #取出数据集中的最小值 将每列的最小值放在minVals中
    maxVals = dataSet.max(0)    #取出数据集中的最大值 将每列的最大值放在maxVals中  
    ranges = maxVals - minVals  #计算取值范围
    normDataSet = np.zeros(np.shape(dataSet))#初始化一个矩阵,该矩阵和所给数据集维度相同用于存放归一化之后的数据
    m = dataSet.shape[0]
    normDataSet = dataSet - np.tile(minVals, (m,1))  #这里tile()函数创建了一个以min_value为值的m行列向量,然后计算oldValue-min_value
    print(minVals)
    print(maxVals)
    print(np.tile(minVals,(m,1)))
    normDataSet = normDataSet/np.tile(ranges, (m,1)) #特征值相除得到归一化后的数值
    return normDataSet, ranges, minVals

五、测试数据

'''
思路就是1.读取数据 
                2.划分数据测试数据和训练数据
                3.数据归一 减少误差
                4.匹配距离算法 提取最近距离作为结果
                5.误差分析 真是值和预测值
                         
'''
def datingClassTest():
    hoRatio = 0.50      #hold out 10%
    project_dir = dire.getProjectPath()
    datingDataMat,datingLabels = file2matrix(project_dir+'/'+'datingTestSet2.txt')       #load data setfrom file
    normMat, ranges, minVals = autoNorm(datingDataMat)
    m = normMat.shape[0]
    numTestVecs = int(m*hoRatio)
    errorCount = 0.0
    for i in range(numTestVecs):
        classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
        print ("the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i]))
        if (classifierResult != datingLabels[i]): errorCount += 1.0
    print ("the total error rate is: %f" % (errorCount/float(numTestVecs)))
    print (errorCount)

六、手写字体识别

'''
手写字体识别
思路跟上面的那个差不多
这里把手写的字体弄成了一个文件-》可以理解为图片的像素值
这里有个问题这是对与处理规格一样的文件,如何把图片都搞成基本一直的哪?
'''
def handwritingClassTest():
    hwLabels = []
    project_dir = dire.getProjectPath()
    trainingFileList = os.listdir(project_dir+"/"+'trainingDigits')           #load the training set
    m = len(trainingFileList)
    trainingMat = np.zeros((m,1024))
    for i in range(m):
        fileNameStr = trainingFileList[i]
        fileStr = fileNameStr.split('.')[0]     #take off .txt
        classNumStr = int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        trainingMat[i,:] = img2vector(project_dir+"/"+'trainingDigits/%s' % fileNameStr)
    testFileList = os.listdir(project_dir+"/"+'testDigits')        #iterate through the test set
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        fileNameStr = testFileList[i]
        fileStr = fileNameStr.split('.')[0]     #take off .txt
        classNumStr = int(fileStr.split('_')[0])
        vectorUnderTest = img2vector(project_dir+"/"+'testDigits/%s' % fileNameStr)
        classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
        print ("the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))
        if (classifierResult != classNumStr): errorCount += 1.0
    print ("\nthe total number of errors is: %d" % errorCount)
    print ("\nthe total error rate is: %f" % (errorCount/float(mTest)))
00000000000001111000000000000000
00000000000011111110000000000000
00000000001111111111000000000000
00000001111111111111100000000000
00000001111111011111100000000000
00000011111110000011110000000000
00000011111110000000111000000000
00000011111110000000111100000000
00000011111110000000011100000000
00000011111110000000011100000000
00000011111100000000011110000000
00000011111100000000001110000000
00000011111100000000001110000000
00000001111110000000000111000000
00000001111110000000000111000000
00000001111110000000000111000000
00000001111110000000000111000000
00000011111110000000001111000000
00000011110110000000001111000000
00000011110000000000011110000000
00000001111000000000001111000000
00000001111000000000011111000000
00000001111000000000111110000000
00000001111000000001111100000000
00000000111000000111111000000000
00000000111100011111110000000000
00000000111111111111110000000000
00000000011111111111110000000000
00000000011111111111100000000000
00000000001111111110000000000000
00000000000111110000000000000000
00000000000011000000000000000000

转载于:https://my.oschina.net/findurl/blog/1561147