数据建模及常见分类算法

1.python数据建模概述

数据建模指的是对现实世界各类数据的抽象组织,建立一个适合的模型对数据进行处理。

在数据分析与挖掘中,我们通常需要根据一些数据建立起特定的模型,然后处理。模型的建立需要依赖于算法,一般,常见的算法有分类(有明确类别)、聚类(无明确类别)、关联、回归等。

2.python数据分类实现过程

数据分类主要处理现实生活中的分类问题,一般处理思路如下:

(1)首先明确需求并对数据进行观察;

(2)其次,确定算法;

(3)确定步骤;

(4)编程实现。

3.常见的分类算法

(1)KNN算法(k-近邻算法):实现简单的分类(验证码识别)

KNN算法的实现步骤:处理数据 -> 数据向量化 -> 计算欧几里得距离 -> 根据距离进行分类(排序)

例子:KNN算法与手写体数字识别

from numpy import *
import operator
import os
def knn(k,testdata,traindata,labels):  #取k个、测试集、训练集、类别名
    traindatasize=traindata.shape[0]   #调用shape查看行列数,shape[0] 是行
    dif=tile(testdata,(traindatasize,1))-traindata   #tile:将测试集拓展为与训练集一样的维数,以便后面作差求距离
    #a=array([1,5,6])
    #tail(a,2) #表示按行扩展2次
    #b=tail(a,(2,1)) #参数1表示按列扩展,参数2表示扩展2次
    sqdif=dif**2
    sumsqdif=sqdif.sum(axis=1)  #每一行的各列求和
    #b.sum()  #b是一个矩阵,表示b的所有元素求和
    #b.sum(axis=1)  #表示b的行分别求和
    #b.sum(axis=0)  #表示b的行分别求和
    distance=sumsqdif**0.5  #开方,即距离
    sortdistance=distance.argsort()  #对里面的元素按升序排序,得到下标
    count={}
    for i in range(0,k):
        vote=labels[sortdistance[i]]  #决定哪个类别多一点,类别下标是哪个,最后确定分类就是哪一个
        #整理成字典格式
        #c={}
        #c[5]=c.get(5,0)+1  #这样使c出现了一次,循环进行
        count[vote]=count.get(vote,0)+1  #vote是类别 count表示给它计数
    sortcount=sorted(count.items(),key=operator.itemgetter(1),reverse=True)  #降序
    return sortcount[0][0]  #就是最后得到的类别
        
#处理图片
#1.如何将图片转化为文本格式
# 使用pillow模块  安装pip3 install pillow
#先将所有图片转为固定宽高,比如32*32,然后再转化为文本
#import pillow as pil
from PIL import Image   #注意这里的Image的I是大写
ima=Image.open("D:/应用软件/python/class6/weixin.jpg")
fh=open("D:/应用软件/python/class6/weixin.txt","a")  #创建文本文件,用来保存0,1文件
ima.save("D:/应用软件/python/class6/weixincopy.bmp")  #可直接保存为另一个图片
print(ima.size)   #获取图片的长和宽
width=ima.size[0]
height=ima.size[1]
#k=ima.getpixel((1,9))  #获取x=1,y=9的像素值
#print(k)
for i in range(0,width):
    for j in range(0,height):
        color=ima.getpixel((i,j))  #得到三通道值
        colorall=color[0]+color[1]+color[2]  #计算三个通道总的像素值
        if(colorall==0):  #黑色
            fh.write("1")
        else:
            fh.write("0")   
    fh.write("\n")  #读完一行就换行
fh.close()

#加载数据
def datatoarray(fname):  #参数:文件名字
    arr=[]
    #fh=open(fname,encoding='UTF-8')
    fh=open(fname,mode='r',encoding='UTF-8')  #改了的
    for i in range(0,32):
        thisline=fh.readline()
        #thisline=str(fh.readline())   也不行
        for j in range(0,32):
            arr.append(int(thisline[j]))
    return arr
arr1=datatoarray("D:/应用软件/python/class6/traindata/1_7.txt")   #检查是否能够加载 
print(arr1)   #已验证,确实可以实现加载数据
#1_7.txt若是打开过,肯会出现IndexError: string index out of range的错误,具体原因未知

#建立一个函数取文件的前缀
def seplabel(fname):
    filestr=fname.split(".")[0]  #分隔“.”,取第一个
    label=int(filestr.split("_")[0])  #分隔“_”
    return label

#建立训练数据
from os import listdir  #是os模块下的
def traindata():
    labels=[]  #建立一个空的
    trainfile=listdir("D:/应用软件/python/class6/traindata")  #得到一个文件夹下面的所有文件名
    num=len(trainfile)   #列表trainfile有多少个文件,用len
    #行长度32*32=1024(列),每一行存储一个文件
    #用一个数组存储所有训练数据,行:文件总数,列:1024
    #zeros((2,5))  #numpy下的生成2行5列的数组
    trainarr=zeros((num,1024))  #num个文件
    for i in range(0,num):  #将真实数据放到trainarr中
        thisfname=trainfile[i]
        thislabel=seplabel(thisfname)   #要取前缀
        labels.append(thislabel)  #添加数据进去
        trainarr[i,:]=datatoarray("D:/应用软件/python/class6/traindata/"+thisfname)  #当前目录下
        #trainarr[i,:]=datatoarray("traindata/"+thisfname)  #当前目录下
    return trainarr,labels

'''
#用测试数据调用KNN算法去测试门槛是否能够准确识别
def datatest():
    trainarr,labels=traindata()  #得到训练集和标签
    #testlist=listdir("D:/应用软件/python/class6/testdata")  #得到测试集
    testlist=listdir("testdata/")  #得到测试集
    tnum=len(testlist)
    for i in range(0,tnum):
        thistestfile=testlist[i]   #得到当前的测试文件
        #进行测试,首先加载为数组
        #testarr=datatoarray("D:/应用软件/python/class6/testdata/"+thistestfile)
        testarr=datatoarray("testdata/"+thistestfile)
        rknn=knn(3,testarr,trainarr,labels)
        print(rknn)
        
datatest() #调用函数   调用出错
'''

#抽某一个测试文件出来进行试验
trainarr,labels=traindata()  #得到训练集和标签
thistestfile="6_50.txt"  
testarr=datatoarray("D:/应用软件/python/class6/testdata/"+thistestfile)
rknn=knn(3,testarr,trainarr,labels)
print(rknn)

正常情况下,经过knn算法能够识别出测试集的数字是0-9的哪个数。我的出现以下错误,未解决:

代码还可参考:

https://www.cnblogs.com/d0main/p/6683427.html

https://blog.csdn.net/waitfou/article/details/70978183

[Errno 2] No such file or directory: 'traingingDigits/0_0.txt'问题解决参考:https://blog.csdn.net/jiaoyangwm/article/details/79524222

(2)贝叶斯算法

首先,贝叶斯公式如下:

p(B_{i}|A)=\frac{p(B_{i})p(A|B_{i})}{\sum_{j=1}^{n}p(B_{j})p(A|B_{j})}

贝叶斯分类思想:https://blog.csdn.net/oppo62258801/article/details/75044699

class Bayes:  #定义一个贝叶斯类
    def __init__(self):   #对类进行初始化
        self.length=-1    #初始化变量长度
        self.labelcount=dict() #类别标签,并用空字典存储
        self.vectorcount=dict()#向量
    def fit(self,dataSet:list,labels:list): #训练方法,数据集,标签集 用:list指定类别
        if(len(dataSet)!=len(labels)):  #训练方法中,数据集与标签集的长度应该一致
            raise ValueError("您输入的测试数组与类别数组长度不一致")  #提示出错,用raise引发异常
        self.length=len(dataSet[0])  #定义长度 测试数据中任一维的长度,就是它特征值的长度
        labelsnum=len(labels)   #类别所有的数量
        norlabel=set(labels)    #不重复类别的数量 通过集合set方法出去重复的
        for item in norlabels:  #依次遍历各个类别
            thislabel=item      #当前类别占总类别的比例
            labelcount[thislabel]=labels.count(thislabel)/labelsnum
        for vector,label in zip(dataSet,labels):    #遍历测试数据的类别和向量
            if(label not in vectorcount):         #label不在里面,则对其进行初始化
                self.vectorcount[label]=[]
            self.vectorcount[label].append(vector)
        print("训练结束")
        return self
    def btest(self,TestData,labelSet):  #将当前的测试数据、对应的类别集合输入
        if(self.length==-1):
            raise ValueError("您还没有进行训练,请先训练")
        #计算testdata分别为各个类别的概率
        lbDict=dict()
        for thislb in labelSet:  #依次遍历各个类别
            p=1   #后面公式用
            alllabel=self.labelcount[thislb]  #统计当前类别占总类别的比例
            allvector=self.vectorcount[thislb]
            vnum=len(allvector)
            allvector=numpy.array(allvector).T
            for index in range(0,len(TestData)):
                vector=list(allvector[index])
                p*=vector.count(TestData[index])/vnum  #计算当前特征的概率
            lbDict[thislb]=p*alllabel
        thisislabel=sorted(lbDict,key=lambda x:lbDict[x],reverse=True)[0]  #从大到小排序reverse=True
        return thisislabel

if __name__ == "__main__":
    by1=Bayes()
    #by1.fit()

这儿还讲了sklearn神经网络模块的下载

回归算法:拟合一条线

线性回归、逻辑回归、非线性回归、主成分回归

https://www.cnblogs.com/sparkwen/p/3441197.html

逻辑回归:概率p、1-p,求比值,取对数,用e表示出p的函数,即是逻辑函数

(3)决策树

(4)人工神经网络

(5)支持向量机

猜你喜欢

转载自blog.csdn.net/juliarjuliar/article/details/81062191