在入门机器学习之前必须要知道,很多的数据并不会照我们想的那样十分完美,比如数据残缺,单位不统一等都会使我们的机器无法完成正常的学习,甚至会出现程序的报错。因此,学习如何对数据进行预处理是很有必要的。以下文章就是对预处理的一些代码的实现和讲解。 数据的下载地址点击下载 提取码 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,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数据归一化函数构建完毕 以上的内容就是用基础函数库实现数据的预处理 ######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
#机器学习第一课数据预处理到这里就应该结束了,欢迎大家学习交流啊! [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
