1.数据类型的分析(假设数据为'data.csv')
首先读入数据,这个数据是csv格式,可以用pandas来读,如果读不进来的时候,可以用记事本打开'data.csv'然后另存为'data_2.csv'并且保存为'utf-8'的编码格式。然后读取数据。
import pandas as pd
'''read data'''
data = pd.read_csv('data_2.csv')
row, col = data.shape
在Variable explorer 里可以看到读入的data,在这里为了方便给出部分数据,从下图中可以看到数据中既有数字,也有汉字,字符,时间数据,此外还有缺失值nan,除此之外还有一些对数据分类没有用的特征,因此接下来我们需要对数据进行无关特征的剔除。
2.无关特征剔除
在此数据中,由于是金融数据并预测贷款用户是否会逾期,暂时将两个对分类结果无关的特征剔除
data.drop('bank_card_no',axis = 1, inplace = True)
data.drop('id_name',axis = 1, inplace = True)
3.缺失值处理一
对于缺失值,最简单的方法就是将所有缺失的数据删掉(data=data.dropna()),但是如果缺失数据较多时会造成可用数据量减少,此数据原始数据为:4754×90,如果将缺失全部删掉,数据为1534×90,因此需要对此数据进行填补,在对此数据进行填补前需要先考虑数据的缺失情况。为避免缺失数据过多造成填补的结果有偏差,本次对数据的特征或者样本超过0.2%的进行删除。(这是根据此数据情况进行删除的,数据的缺失率不同,删除缺失的情况也不同)
data=data.dropna()
def miss_row(data):
row,col = data.shape
row_miss = []
del_ = []
for i in range(row):
w = data.iloc[i,:].isnull().sum()
ratio = w.sum()/row
row_miss.append(ratio)
if ratio > 0.002:
del_.append(i)
row_miss = pd.Series(row_miss)
row_percent = row_miss.sort_values(axis = 0,ascending = False)
data_ = data[row_percent<0.002]
return row_percent, data_
def miss_col(data):
col_percent = (data.isnull().sum()/data.isnull().count()).sort_values(ascending=False)
names = col_percent[col_percent<0.002].index
data_ = data[names]
return col_percent, data_
row_percent, data_0 = miss_row(data)
col_percent, data_1 = miss_col(data_0)
data_1.to_csv('data_clear.csv')
3.数据类型转换
这里定义了一个函数w2_n,用来将非数值类型的数据转换为数值,方便后续处理。
from sklearn.preprocessing import LabelEncoder
def w2_n(data):
data_label_num = data.copy()
class_le = LabelEncoder()
#用class_le.fit_transform将其转换
data_label_num['reg_preference_for_trad'] = class_le.fit_transform(data_label_num['reg_preference_for_trad'].values)
data_label_num['source'] = class_le.fit_transform(data_label_num['source'].values)
data_label_num['loans_latest_time'] = class_le.fit_transform(data_label_num['loans_latest_time'].values)
data_label_num['latest_query_time'] = class_le.fit_transform(data_label_num['latest_query_time'].values)
#转换完成,我们可以看下转换后的类别情况
# label= np.unique(data_label_num['reg_preference_for_trad'])
return data_label_num
data = w2_n(data)
5.缺失值处理二
在第3步中只是对部分缺失值进行了删除但是并没有对其进行填补,这一步即对上述缺失数据进行填补,此处采用 的是em方法进行填补(是在github中看到的一个比较简单好用的方法https://github.com/eltonlaw/impyute),也可以用其他的方法。个人觉得目前最好的方法是2018年ICML中的一篇论文GAIN: Missing Data Imputation using Generative Adversarial Nets,感兴趣的可以看看:paper链接http://medianetlab.ee.ucla.edu/papers/ICML_GAIN.pdf;补充材料链接http://medianetlab.ee.ucla.edu/papers/ICML_GAIN_Supp.pdf。
此处采用的方法在填补之后会将数据的columns消掉,所以在填补之前需要先保存数据的列名以及提取出类别标签'status'
import impyute as impy
label = data['status']#get label
data_2.drop('status',axis = 1, inplace = True)
names = data_2.columns
data_com = impy.em(np.array(data_2,dtype = np.float))
5.删除方差较小的特征(对分类结果影响较小)
这里用sklearn中VarianceThreshold,
from sklearn.feature_selection import VarianceThreshold
#删除方差较小的特征
var = VarianceThreshold(threshold=1.0) # 将方差小于等于1.0的特征删除。 默认threshold=0.0
data = var.fit_transform(data)
6.数据归一化(0-1之间)
def min_max(data):
Min_Val = np.zeros(data.shape[1])
Max_Val = np.zeros(data.shape[1])
for i in range(data.shape[1]):
Min_Val[i] = np.min(data[:,i])
data[:,i] = data[:,i] - np.min(data[:,i])
Max_Val[i] = np.max(data[:,i])
data[:,i] = data[:,i] / (np.max(data[:,i]) - np.min(data[:,i]) + 1e-6)
return data
data = min_max(data)
7.划分训练测试数据集(这里使用的是训练数据70%,测试数据30%,也可以使用K折交叉验证)
在划分好测试训练数据后是将数据打乱,然后选择训练和测试数据的编号
def split(data,label):
train_rate = 0.7
row,col = data.shape
trainNo = int(row*train_rate)
idx = np.random.permutation(row)
train_data = data[idx[0:trainNo],:]
test_data = data[idx[trainNo:],:]
train_label = label[idx[0:trainNo]]
test_label = label[idx[trainNo:]]
return train_data, train_label, test_data, test_label
train_data, train_label, test_data, test_label = split(data,label)
8.对数据进行分类
from tqdm import tqdm
def RF_classify(train_data, train_label, test_data, test_label):
forest = RandomForestClassifier(n_estimators=15, random_state=0, n_jobs=-1)
forest.fit(train_data, train_label) #training
# pre_rf = forest.predict(x_test)
ac_train = forest.score(test_data, test_label)
return ac_train
ac = []
for i in tqdm(range(1000)):
train_data, train_label, test_data, test_label = split(data_4,label)
acc = RF_classify(train_data, train_label, test_data, test_label)
ac.append(acc)
print('The RF classify acc:.{:.4}'.format(np.mean(ac)))
到此基本就已经结束了,不过这里使用的都是一些基本简单的方法来进行数据分类的一个过程,其中包括数据的处理包括类别转换,缺失值处理,特征选择(这里只用了一个方差的,其他的许多方法后续再写,最后用了一个随机森林进行分类)