建模时,常常会遇到有些特征变量代表的是类型或类型。比如城市(city),它的取值有San Francisco,New York和Seattle三种。代表三个城市。
import pandas as pd from sklearn import linear_model df = pd.DataFrame({'City': ['SF', 'SF', 'SF', 'NYC', 'NYC', 'NYC','Seattle', 'Seattle', 'Seattle'], 'Rent': [3999, 4000, 4001, 3499, 3500, 3501, 2499,2500,2501]}) City Rent 0 SF 3999 1 SF 4000 2 SF 4001 3 NYC 3499 4 NYC 3500 5 NYC 3501 6 Seattle 2499 7 Seattle 2500 8 Seattle 2501对于这样的变量肯定要数值化。可能很多人会想到做这样的映射:{San Francisco:1,New York:2,Seattle:3}。
做如上处理后,数据变为:
City Rent 0 1 3999 1 1 4000 2 1 4001 3 2 3499 4 2 3500 5 2 3501 6 3 2499 7 3 2500 8 3 2501对其采用线性回归建模:
model = linear_model.LinearRegression() model.fit(df2[['City']],df2[['Rent']]) #查看模型参数,线性模型的斜率和截距 model.coef_ model.intercept_ #输出模型参数 array([[-750.]]) array([4833.33333333])将类别特征进行表示一个最好的办法就是使用一组比特位来表达。每一位代表一个可能的类别。 如果该变量不能一次成为多个类别,那么该组中只有一位可以是1。 这被称为独热编码,它在Scikit Learn中实现sklearn.preprocessing.OneHotEncoder。 每个位都是一个特征。 因此是一个绝对的具有k个可能类别的变量被编码为长度为k的特征向量。
表 对3个城市的类别进行独热编码
Citye1e2e3San Francisco100New York010Seattle001独热编码非常易于理解。 但它使用的是比严格必要的更多的一点。 如果我们看到k-1位是零,那么最后一位必须是1,因为变量必须具有k个值中的一个。 在数学上,可以写下这个约束条件为“所有位的和必须等于1”。
独热编码e1,e2,e3限制条件。
e1+e2+e3+...+ek=1
因此,我们有一个线性的依赖性。 线性相关特征,就像我们一样在tfidf中发现,有点烦人,因为它意味着训练线性模型不会是唯一的。 特征的不同线性组合可以做出同样的预测,所以我们需要跳过额外条件的来理解特征对预测的影响。
我们看下采用one-hot编码后的数据建模效果如何。
#one-hot编码,将city的列,重新以city为前缀产生新的列 one_hot_df = pd.get_dummies(df, prefix=['city'])输出新的数据集:
Rent city_NYC city_SF city_Seattle 0 3999 0 1 0 1 4000 0 1 0 2 4001 0 1 0 3 3499 1 0 0 4 3500 1 0 0 5 3501 1 0 0 6 2499 0 0 1 7 2500 0 0 1 8 2501 0 0 1建模:
model = linear_model.LinearRegression() model.fit(one_hot_df[['city_NYC', 'city_SF', 'city_Seattle']],one_hot_df[['Rent']])查看模型参数:
model.coef_ model.intercept_结果:
array([[ 166.66666667, 666.66666667, -833.33333333]]) array([3333.33333333])可以看到,经过one-hot编码后,模型的误差明细减少,同时模型也更具可解释性。