加州房价预测 [Hands On ML] 2. 一个完整的机器学习项目( 三 )


文章插图
8. 特征组合
数据在交给算法之前,最后一件事是尝试多种属性组合
例如,如果你不知道某个街区有多少户,该街区的总房间数就没什么用 。你真正需要的是每户有几个房间 。
相似的,总卧室数也不重要:你可能需要将其与房间数进行比较 。每户的人口数也是一个有趣的属性组合 。
# 每家的房间数housing["rooms_per_household"] = housing["total_rooms"]/housing["households"]# 每家的卧室数量比housing["bedrooms_per_room"] = housing["total_bedrooms"]/housing["total_rooms"]# 每家的人口housing["population_per_household"]=housing["population"]/housing["households"]corr_mat = housing.corr()corr_mat['median_house_value'].sort_values(ascending=False)
median_house_value1.000000median_income0.684828rooms_per_household0.171947# 新特征1total_rooms0.133566# 1a3bhousing_median_age0.107684households0.065778# 1b2btotal_bedrooms0.049941# 3apopulation-0.025008# 2apopulation_per_household-0.026596# 新特征2longitude-0.043824latitude-0.146748bedrooms_per_room-0.256396# 新特征3Name: median_house_value, dtype: float64
可以看出新的特征比原特征,与房价之间有更高的相关性
9. 为算法准备数据
尽量写一些函数来处理,以便复用,代码也更清晰
分离 特征 与 标签housing = strat_train_set.drop('median_house_value',axis=1)housing_label = strat_train_set['median_house_value'].copy()
9.1 数据清洗
有缺失,可以:
housing.dropna(subset=["total_bedrooms"])# 选项1housing.drop("total_bedrooms", axis=1)# 选项2median = housing["total_bedrooms"].median()记得保存,后序填补test集housing["total_bedrooms"].fillna(median)# 选项3
from sklearn.impute import SimpleImputerimpter = SimpleImputer(strategy='median')# 数值属性才能计算中位数housing_num = housing.drop('ocean_proximity',axis=1)impter.fit(housing_num)impter.statistics_
array([-118.49,34.26,29., 2122.5,434.,1163.,409.,3.52945])
housing_num.median().values
跟上面一样array([-118.49,34.26,29., 2122.5,434.,1163.,409.,3.52945])
应用转换,填补确实数据为中位数
X = impter.transform(housing_num)type(X) # numpy.ndarray
转换完为 numpy 数组,再转回
housing_tr = pd.DataFrame(X, columns=housing_num.columns)type(housing_tr)# pandas.core.frame.DataFrame
9.2 处理文本特征
from sklearn.preprocessing import LabelEncoderencoder = LabelEncoder() # 只能对第一文本列,多文本列使用pd.factorize()housing_cat = housing['ocean_proximity']housing_cat_encoded = encoder.fit_transform(housing_cat)housing_cat_encodedprint(encoder.classes_)
['<1H OCEAN' 'INLAND' 'ISLAND' 'NEAR BAY' 'NEAR OCEAN']
这样做,标签对应于 0,1,2,算法在计算距离相似度的时候,会产生偏差:(0,4显然比0,1更相似)
采用 独热编码(One-Hot ),只有一个属性会等于 1(热),其余会是 0(冷),计算距离相似度的时候更合理
from sklearn.preprocessing import OneHotEncoderencoder = OneHotEncoder()housing_cat_1hot = encoder.fit_transform(housing_cat_encoded.reshape(-1,1))注意:需要单列数据需要 reshape(-1,1),转成矩阵