预处理的重要性:无论是分类还是预测,都可以提高准确率
编码
字符串转数值型
字符串分类变量一般都是object
X = rawdata.iloc[:,0:-1]
X.dtypes
"object"
方法一
for col in X.columns:
if X[col].dtype == "O":
X[col] = pd.Categorical(X[col]).codes
好处是快,缺点是不知道映射的规则是啥。如果想要自定义——
方法二
marital_mapping = {"married":1, "single":2, "divorced":3}
X["marital"] = X["marital"].map(marital_mapping)
或者:
X.replace(dict(primary=1, secondary=2, tertiary=3), inplace=True)
dataset.loc[:, "contact"].replace(dict(cellular=0, telephone=1), inplace=True)
如果类别特别多可以采用以下方法——
方法三
job_mapping = {label:idx for idx,label in enumerate(set(X["job"]))}
X["job"] = X["job"].map(job_mapping)
print(enumerate(set(X["job"])))
可以通过set(X["job"])
观察对应关系,缺点是不能自定义
缺失值填充
众数、中位数、特值等填充
直接查看数据集,replace即可
dataset["job"].value_counts()
dataset.loc[:, "job"].replace(np.nan, "blue-collar", inplace=True)
KNN填充
必须在编码之后完成。原理是取最相似的n个样本在该属性下的平均值。
from sklearn.impute import KNNImputer
imputer = KNNImputer(n_neighbors=5)
dataset_knn = pd.DataFrame(imputer.fit_transform(dataset), columns=dataset.columns)
注意:
fit_transform
得到新的np.array
,需要重新赋值;- sklearn库自带的KNNImputer似乎只能取平均值,不能取频次最多的数。所以不适合分类变量。
对分类变量的处理:(四舍五入了一下)
dataset_knn.loc[:, "education"] = np.round(dataset_knn["education"], decimals=0)
独热变量
注意:pandas Dataframe dtype必须是“O”。字符串可以,数值不行
把所有的object都变成独热变量
y = pd.get_dummies(y)
属性取值多的话时间较长。
标准化
from sklearn.preprocessing import StandardScaler
dataset.loc[:,"age"] = StandardScaler().fit_transform(np.array(dataset["age"]).reshape(-1,1))
reshape(-1,1)
的作用是把array打平成1列(2维array)
分箱
基本是按照经验来分。cut等宽,qcut等频
age = pd.cut(X["age"], 10, labels=[1,2,3,4,5,6,7,8,9,10])
balance = pd.qcut(X["balance"], 5, labels=[1,2,3,4,5])