在入门机器学习之前必须要知道,很多的数据并不会照我们想的那样十分完美,比如数据残缺,单位不统一等都会使我们的机器无法完成正常的学习,甚至会出现程序的报错。因此,学习如何对数据进行预处理是很有必要的。以下文章就是对预处理的一些代码的实现和讲解。
数据的下载地址点击下载 提取码 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
机器学习使我快乐,呵呵机器学习第一课数据预处理到这里就应该结束了,欢迎大家学习交流啊!
网友评论