进击的机器学习 First Day——数据预处理

作者: 焜俞 | 来源:发表于2019-11-02 22:25 被阅读0次

在入门机器学习之前必须要知道,很多的数据并不会照我们想的那样十分完美,比如数据残缺,单位不统一等都会使我们的机器无法完成正常的学习,甚至会出现程序的报错。因此,学习如何对数据进行预处理是很有必要的。以下文章就是对预处理的一些代码的实现和讲解。
数据的下载地址点击下载 提取码 t6if

第一个:调包侠专用(纯属调侃啊,用起来比较方便)基于sklearn和pandas库

导入数据

   Country   Age   Salary Purchased
0   France  44.0  72000.0         0
1    Spain  27.0  48000.0         1
2  Germany  30.0  54000.0         0
3    Spain  38.0  61000.0         0
4  Germany  40.0      NaN         1
5   France  35.0  58000.0         1
6    Spain   NaN  52000.0         0
7   France  48.0  79000.0         1
8  Germany  50.0  83000.0         0
9   France  37.0  67000.0         1
#数据长这样:不同国家,年龄,收入的人对这件商品是否购买,0表示不购买,1表示购买
#我们要处理什么呢:第一个NaN的缺失值该怎么做掉
第二个这些国家的名字作为自变量对机器学习来说无法进行学习,该怎样把他们变成数据让数据学习
import pandas as pd #导入Pandas库
dataset=pd.read_csv(path)#读取数据到dataset,path是文件路径
x=dataset.iloc[:,0:3].values#pandas的一个iloc属性,选择x数据的范围
#注意:values一定要加上,否则数据数据只是可看不可读写
#x一定是一个二维数组哦,类似[[],]这种,否则sklearn会处理报错
y=dataset.iloc[:,3].values

处理丢失的数据

from sklearn.preprocessing import Imputer,LabelEncoder,OneHotEncoder
#从preprocessing里面导入Imputer(处理丢失数据)
#LabelEncoder(将一些属性标签化,不懂的话往后看)
#OneHotEncoder将标签化的数据再进一步处理为one-hot编码(不懂会有解答)
imputer=Imputer(missing_values='NaN',strategy='mean',axis=0)
#首先将Imputer实例化,参数missing_values顾名思义
#strategy是将缺失值修复的方法,这里mean是平均值,还有median(中值)
#抑或是most-frequent(众数)
#axis的0按列处理,1是按行处理
imputer.fit(x[:,1:])#让imputer去处理x的第二列以后的丢失的数据
x[:,1:]=imputer.transform(x[:,1:])#将处理后的数据转化给原来的x

将特定属性标签化

LE=LabelEncoder()#实例化标签化 类
x[:,0]=LE.fit_transform(x[:,0])
y[:]=LE.fit_transform(y[:])
#以上就是LE如何将指定的列的数据进行标签化
#下一步将标签化的数据进行one-hot编码
onehotencoder=OneHotEncoder(categorical_features = [0])
#同样先实例化,里面参数可要可不要
X = onehotencoder.fit_transform(X).toarray()
#将属性X进行转化,完成one-hot编码

数据打散为训练集和测试集

from sklearn.model_selection import train_test_split
#废话不多说,导入包就完事了
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=0)
#首先参数x,y是数组格式,要和前面一一对应
#test_size指定测试集的占比,如果是整数的化就是指定数据数量
#random_state指定随机数种子,实验具有可复性

最后一步,数据归一化

from sklearn.preprocessing import StandardScaler
sd=StandardScaler()#还是先进行实例化
x_train=sd.fit_transform(x_train)
x_test=sd.fit_transform(x_test)
#数据归一化处理完毕

以上就是调包侠处理数据的过程,有sklearn我就是个爸爸,不服咬我啊
问题解答:

1、Q:为什么对一些特征标签化呢?
A:因为我们给出的数据比如说国家名称,机器无法进行运算,我们将它标签化为0,1,2等与国家相对应,机器就可以处理了。进一步one-hot编码更适合机器使用
2、Q:为什么要将数据进行归一化处理呢?
A:为了使数据更加的平稳,减少噪声
3、Q:如何理解onehot编码呢?
A:比如说有3个国家['中国','日本','美国','中国'],显然这样机器学习算法无法进行运算学习,于是呢我们就一个国家给他们分配一个标签,依次是[0,1,2,0],代表与之相应的国家。但是仅仅是进行这种编码,机器就会认为1代表的美国大于0表的中国,但是我们实际上没那个意思啊。这时进行onehot编码就可以避免这个问题,这里共3个国家,于是创建一个1*3的数值都是0的行向量[0,0,0]。因为0代表中国,那么行向量索引为0的值变为1,即中国的onehot编码就是[1,0,0]。同理日本是[0,1,0],美国是[0,0,1]。这样就没大小比较啦!

第二个 自己动手实现数据的预处理(请喊我埼玉sai sai) numpy埼玉

在接下来的教程中我们仅仅使用numpy,pandas,matplotlib,机器学习基础工具来实现上述一系列对数据的预处理。有的人可能要嘲讽了:我是想不开了吗?sklearn它不香吗? 其实并不香
sklearn确实是机器学习的一个强大工具,但是要知道它只是一个黑盒子,你不知道原理是什么,只知道调用其中的这个函数会这种效果,这其实是不利于我们机器学习的。好,废话不多说,开始发车。

导入数据 还是和之前一样

import numpy as np
import pandas as pd
import math
dataset=pd.read_csv(path)#传入文件地址
#分别导入数据
x=dataset.iloc[:,0:3].values
y=dataset.iloc[:,3].values

导入数据完毕

创建数据丢失处理函数

#目前我只做了平均值和列方向的处理方式。欢迎大家完善啊
def PreMissValues(x=np.zeros((3,3)),axis=1,strategy='mean'):
    rows,columns=x.shape#获取传入的x形状
    if axis==1:#传入对列的操作指令
        for j in range(columns):#对列进行迭代
            column_sum=0#列的和
            sign_position=[]#丢失值的位置
            num=0#除去丢失值,某列的元素个数
            for i in range(rows):#对行进行迭代
                if type(x[i][j])==str:
                    continue#如果是非数值型的数据,我们直接跳过
                if not math.isnan(x[i,j]):#这是判断数据是否是NaN型丢失数据
                    column_sum+=x[i][j]#不是的话,求和
                    num+=1#元素个数记录,为了求均值。(所以其他策略都是可以实现的)
                else:
                    sign_position.append((i,j))#如果是丢失数据类型,记录它的位置
                    continue
                for position in sign_position:
                    x_p,y_p=position
                    x[x_p][y_p]=column_sum/num#将丢失数据的值按平均值赋给它
    return x

处理丢失值数据函数构建完毕

数据标签化

def label_to_values(x=np.zeros((3,3)),axis=1,ohe='y'):
#是否进行onehot编码(ohe)
    if len(list(x.shape))==2:#判断传入的数组是特征值,还是目标值(所以我说x是[[]]类型,而y是[]类型)
        rows,columns=x.shape#获取形状
        if axis==1:#对列处理
            for j in range(columns):#对列进行迭代
                label={}#获取标签字典,并用自然数指代
                num=0#字典的自然数
                for i in range(rows):#对行进行迭代
                    if x[i][j] in label.keys():#判断元素是否已经存在在字典中
                        continue
                    if type(x[i,j])==str:#判断元素是否是非数值型
                        key=x[i,j]#是的话,获取作为键值
                        label[key]=num#键值对应的标签
                        num+=1
                for i in range(rows):#对行进行迭代
                    if type(x[i,j])==str:
                        x[i,j]=label.get(x[i,j])#将键值替换为其对的值,完成标签化
                if ohe=='y':#是否onehot编码
                    x=x.tolist()#首先将x转换为列表,便于处理
                    for a in range(rows):#沿着上面对行迭代
                        onehot=[]#初始onehot的列表
                        for m in range(len(label)):
                            onehot.append(0)#赋值onehot的0
                        if not onehot:
                            break
                        pop=x[a].pop(j)#删除标签值,并获取标签值,作为索引
                        onehot[pop]=1#指定onehot索引值处为1
                        onehot.reverse()#时onehot颠倒位置好加入到x中
                        for element in onehot:
                            x[a].insert(0,element)#将onehot元素插入x中
                    x=np.array(x)#再将x转化为nump数组,onehot编码完毕
#同理下面是对一维数组的处理,不再赘述
    if len(list(x.shape))==1:
        rows=list(x.shape)[0]
        label={}
        num=0
        for i in range(rows):
            if x[i] in label.keys():
                        continue
            if type(x[i])==str:
                        key=x[i]
                        label[key]=num
                        num+=1
        for i in range(rows):
                    if type(x[i])==str:
                        x[i]=label.get(x[i])
    return x

数据标签化函数构建完毕

将数据处理为训练集和测试集

#指定传入参数有拆分比例
def Train_Test_split(x=np.zeros((3,3)),y=np.zeros(3),test_size=0.2):
    length=len(x)#获取传入数组的长度,行数(一行一个训练数据嘛)
    random_index=np.random.permutation(length)#获取随机的索引
    test_position=int(length*test_size)#获取拆分的位置
    x_train=[]
    x_test=[]
    y_train=[]
    y_test=[]#构建训练集和测试集
    for i in range(test_position):
        sign=random_index[i]#获取要分为测试集的索引
        x_test.append(x[sign].tolist())#添加进入测试集
        y_test.append(y[sign])
    for j in range(test_position,length):#将剩下的元素加入训练集
        sign=random_index[j]
        x_train.append(x[sign].tolist())
        y_train.append(y[sign])
    x_train=np.array(x_train)
    x_test=np.array(x_test)
    y_train=np.array(y_train)
    y_test=np.array(y_test)
    return (x_train,x_test,y_train,y_test)#返回一个元组

数据拆分函数构建完毕

数据归一化

def standard_scaler(x=np.zeros((3,3))):
    mean=x.mean()#获取数组的平均值
    std=x.std()#获取数组的标准差
    shape=x.shape#获取数组的形状
    mean_array=np.tile(mean,shape)#构建一个元素都等于平均值,但是形状和x一样的数组
    x=(x-mean_array)/std#数据归一化公式(x-u)/std,这里面用到了矩阵的减法和除法
    return x

数据归一化函数构建完毕
以上的内容就是用基础函数库实现数据的预处理


Python再好也怕买菜
1、Q:math.isnan()是干啥的?
A:判断数据类型是否是NaN
2、Q:np.random.permutation(n)有啥用?
A:生成一个从零0到n-1数组,但是顺序是打乱的,自己尝试一下就懂了
3、Q:np.tile(n,(a,b))用来做什么?
A:生成一个(a,b)数组,元素都是n

机器学习第一课数据预处理到这里就应该结束了,欢迎大家学习交流啊!

机器学习使我快乐,呵呵

相关文章

网友评论

    本文标题:进击的机器学习 First Day——数据预处理

    本文链接:https://www.haomeiwen.com/subject/aynhbctx.html