1.One_Hot:独热编码
代码示例1:
from sklearn.preprocessing import OneHotEncoder
import pandas as pd
data =
[['法师',40,14000],
['辅助',30,13000],
['坦克',31,12000],
['射手',30,14000],
['法师',32,11000]]
data = pd.DataFrame(data,columns = ['role','changci','output'])
#print (data)
#在One-Hot编码之前先将带中文的标称属性转换成数值型
#用简单整数替代
listUniq = data.loc[:,'role'].unique() #去重
#对匹配的元素赋值,不匹配的元素保持原样
for j in range(len(listUniq)):
data.loc[:,'role'] = data.loc[:,'role'].apply(lambda x:j if x == listUniq[j] else x )
print(data)
#用数字给文本属性赋值,保证赋值过的不会重新再赋值
# lambda x:j if x == listUniq[j] else x
# 遍历len(listUniq)次 data.loc[:,'role']
# 发现data.loc[:,'role'] 中有元素与listUniq的元素相同,就赋相对应的整数值
#开始One-Hot编码
temp = data[['role']]
enc = OneHotEncoder()
enc.fit(temp)
#将Matrix类型转换为array类型
temp = enc.transform(temp).toarray()
print (temp)
print ("取值范围整数个数: ",enc.n_values_)
one-hot用在GBDT、XGBoost这些模型里面都挺好的,但是用在逻辑回归里不行。因为逻辑回归要求变量间相互独立,如果你只有一个属性需要做one-hot编码还好,如果你有多个属性需要做one-ont编码,那么当某个样本的多个one-hot属性同时为1时,这两个属性就完全相关了,必然会导致singular error,也就是非奇异矩阵不能求解唯一解,得不出唯一的模型,但是你又不可能把同一个属性的某一个one-hot延伸变量删除。
如果在逻辑回归中入模标称属性,可以直接替换成数值,然后做woe变换,用每个类别的woe值来代替原来的数值,这样既能够避免生成相关性强的变量,又能避开类别间大小无法比较的问题。
参考教程
—————————————————————————————————
2.Get_dummy:哑变量
哑变量就是将原始特征变量转换成以原始特征值分类的多维度的变量,并用是否(0,1)这种方式的新特征值替代和量化。
1.读数据
2.对逐个需要处理的列进行Get_dummy,“for each in dummy_fields”
3.与原数据合并
4.删除被Get_dummy的列
代码示例2:用三种方式实现回归,最后比较准确率
import numpy as np
import pandas as pd
#读取数据
train = pd.read_csv("/train.csv")
test = pd.read_csv("/test.csv")
#删除id列
train.drop('id',axis = 1,inplace = True)
test.drop('id',axis = 1,inplace = True)
#生成哑变量
train2 = train
dummy_city = pd.get_dummies(train2['city'],prefix = 'city')
dummy_hour = pd.get_dummies(train2['hour'],prefix = 'hour')
dummy_weather = pd.get_dummies(train2['weather'],prefix = 'weather')
dummy_wind = pd.get_dummies(train2['wind'],prefix = 'wind')
#原始数据合并
train2 = pd.concat([dummy_city,dummy_hour,dummy_weather,dummy_wind],axis = 1)
#还有些原始数据没填进去
#原来的列已经进行了one-hot编码,所以删除被Dummy过的这一列数据
train2.drop('dummy_city',axis = 1,inplace = True)
train2.drop('dummy_hour',axis = 1,inplace = True)
train2.drop('dummy_weather',axis = 1,inplace = True)
train2.drop('dummy_wind',axis = 1,inplace = True)
#【1.线性回归】
from sklearn.linear_model import LinearRegression
from sklearn.cross_validation import train_test_split
x = train2.drop('y',axis = 1)
y = train2['y']
x_train,x_test,y_train,y_test = train_test_split(x,y,random_state = 5)
linreg = LinearRegression()
linreg.fit(x_train,y_train)
y_pred = linreg.predict(x_test)
# 若预测值是负数,则取0
y_pred = list(map(lambda x: x if x >= 0 else 0, y_pred))
# RMSE分值计算
def score(y_pred,y_test):
return np.sqrt(sum((np.array(y_test) - np.array(y_pred))**2)/len(y_pred))
score(y_pred,y_test)
#【2.决策树回归】
#决策树不需要变量变为哑变量
from sklearn.tree import DecisionTreeRegressor
from sklearn.cross_validation import train_test_split
# 避免过拟合,采用交叉验证,验证集占训练集30%,固定随机种子(random_state)
x = train.drop('y',axis = 1)
y = train['y']
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.3,random_state=5)
# 建立最大深度为5的决策树回归模型
reg = DecisionTreeRegressor(max_depth=5)
reg.fit(x_train, y_train)
y_pred = reg.predict(x_test)
#计算RMSE值
print(np.sqrt(sum((np.array(y_test) - np.array(y_pred))**2)/len(y_pred)))
#【3.xgboost回归】
#xgboost不需要变量变为哑变量
from xgboost import XGBRegressor
from sklearn.cross_validation import train_test_split
x = train.drop('y',axis = 1)
y = train['y']
x_train,x_test,y_train,y_test = train_test_split(x,y,random_state=5)
# 建立一个默认的xgboost回归模型
reg = XGBRegressor(learning_rate = 0.05,max_depth = 5,n_estimators = 500)
reg.fit(x_train, y_train)
y_pred = reg.predict(x_test)
#计算RMSE值
print(np.sqrt(sum((np.array(y_test) - np.array(y_pred))**2)/len(y_pred)))
对于定类类型的数据,建议使用one-hot encoding。定类类型就是纯分类,不排序,没有逻辑关系。比如性别分男和女,男女不存在任何逻辑关系,我们不能说男就比女好,或者相反。再者,中国各省市分类也可以用独热编码,同样各省不存在逻辑关系,这时候使用one-hot encoding会合适些。但注意,一般会舍去一个变量,比如男的对立面肯定是女,那么女就是重复信息,所以保留其中一个变量即可。
对于定序类型的数据,建议使用label encoding。定序类型也是分类,但有排序逻辑关系,等级上高于定类。比如,学历分小学,初中,高中,本科,研究生,各个类别之间存在一定的逻辑,显然研究生学历是最高的,小学最低。这时候使用Label encoding会显得更合适,因为自定义的数字顺序可以不破坏原有逻辑,并与这个逻辑相对应。
对数值大小敏感的模型必须使用one-hot encoding或者Dummy。典型的例子就是LR和SVM。二者的损失函数对数值大小是敏感的,并且变量间的数值大小是有比较意义的。而Label encoding的数字编码没有数值大小的含义,只是一种排序,因此对于这些模型都使用one-hot encoding。
对数值大小不敏感的模型(如树模型)不建议使用one-hot encoding。一般这类模型为树模型。如果分类类别特别多,那么one-hot encoding会分裂出很多特征变量。这时候,如果我们限制了树模型的深度而不能向下分裂的话,一些特征变量可能就因为模型无法继续分裂而被舍弃损失掉了。因此,此种情况下可以考虑使用Label encoding
参考教程
参考教程
热门评论
缺失值对特征工程的威力很大,它可以让训练集和验证集在哑变量转换后的维度不一致,这个需要注意