有关数据集预处理的内容可参阅:数据集预处理
1 打开数据集adult.data
这样的文件本质和csv文件一样,可以通过 pd.read_csv() 读取:
adult = pd.read_csv("C://Users//54719//Desktop//adult.data")
out:
我们可以看到,这是一个32561*15的数据集,读取出来的是DataFrame,最后一列income是这个句数据集的标签,这是一个二分类的数据集。
2 查看每一列的dtype
可以通过 adult.loc[:,列名].dtype 或者 adult[列名].dtype 来查看某一列的dtype:
for i in adult.columns:
print(f"The column {i}'s dtype is {adult.loc[:,i].dtype}")
out:
The column age's dtype is int64
The column workclass's dtype is object
The column fnlwgt's dtype is int64
The column education's dtype is object
The column education-num's dtype is int64
The column marital-status's dtype is object
The column occupation's dtype is object
The column relationship's dtype is object
The column race's dtype is object
The column sex's dtype is object
The column capital-gain's dtype is int64
The column capital-loss's dtype is int64
The column hours-per-week's dtype is int64
The column native-country's dtype is object
The column income's dtype is object
3 处理不同dtype的列
3.1 判断每一列的数据类型
object类的是str,int64类型的数字,我们先收集object类的数据列:
方法一:整体判断
object_columns = adult.dtypes=="object"
object_columns = list(object_columns[object_columns].index)
int_columns = adult.dtypes=="int64"
int_columns = list(int_columns[int_columns].index)
方法二:遍历判断
object_columns = []
int_columns = []
for i in adult.columns:
if adult.loc[:,i].dtype == "object":
object_columns.append(i)
if adult.loc[:,i].dtype == "int64":
int_columns.append(i)
3.2 object类数据的处理
确定每一列是数值类型还是文本类型后,我们先对文本类型的数据进行处理,这里,我们将文本类型的数据转化成one-hot编码,从而有效地区分了每一类之间的欧氏距离。
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
for col_name in object_columns:
values = np.array(adult[col_name])
print(values)
onehot_encoder = OneHotEncoder(sparse=False)
values = values.reshape(len(values), 1)
onehot_matrix = onehot_encoder.fit_transform(values)
print(onehot_matrix)
adult.drop([col_name],axis=1,inplace=True)
# 在 Dataframe 首列插入one-hot后新列
for i in range(onehot_matrix.shape[1]):
adult.insert(0, 'new_'+col_name+"_"+str(i), value=onehot_matrix[:,i])
# 当然,这也可以批量操作(前提是对dataframe数据) 尝试一下:onehot_encoder.fit_transform(adult[object_columns])
out:
我们来看一下操作后的adult:
列数从15列变成了110列!
3.3 数字类型的列的处理
主要就是归一化(缩放到 [-1, 1]),算出均值和方差再处理。
from sklearn.preprocessing import MinMaxScaler
for col_name in int_columns:
Scaler = MinMaxScaler(feature_range=(-1, 1))
col_value = np.array(adult[col_name]).reshape(-1,1)
new_col = Scaler.fit_transform(col_value)
adult[col_name] = new_col
4 划分X和Y
我们要先找到标签列,发现他之前已经被onehot了:
这里,我们假设new_income_0 为0,new_income_1为1,创建新数组,记为Y,并删除adult里的标签列:
Y = (adult.iloc[:,0]==1)
Y = np.array(Y, dtype=int)
adult.drop(["new_income_1","new_income_0"], axis=1, inplace=True)
可以看到列数少了2列,变成108列了。
那么adult剩下的数据就全是X:
X = adult.values
最后把我们划分好的数据保存起来:
np.savez("./Adult_processed.npz", X=X, Y=Y)
如果要再读取数据,这样操作:
#查看保存了哪些数据
with np.load("./Adult_processed.npz") as f:
print(f.files)
out:
然后:
f = np.load("./Adult_processed.npz")
X, Y = f["X"], f["Y"]