《机器学习实战》加州福利尼州房屋价格 数据清理与文本分类

数据清理

由上一阶段的学习,通过info方法我们查看到了数据集的简单描述。

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20640 entries, 0 to 20639
Data columns (total 10 columns):
 #   Column              Non-Null Count  Dtype  
---  ------              --------------  -----  
 0   longitude           20640 non-null  float64
 1   latitude            20640 non-null  float64
 2   housing_median_age  20640 non-null  int64  
 3   total_rooms         20640 non-null  int64  
 4   total_bedrooms      20433 non-null  float64
 5   population          20640 non-null  int64  
 6   households          20640 non-null  int64  
 7   median_income       20640 non-null  float64
 8   median_house_value  20640 non-null  int64  
 9   ocean_proximity     20640 non-null  object 
dtypes: float64(4), int64(5), object(1)
memory usage: 1.6+ MB

我们发现total_bedrooms这个属性其实是缺少数据的,翻开csv文件也
解决它的三个方式:

  1. 放弃这些相应的地区
  2. 放弃这个属性
  3. 将缺失值设置为某个值(0、平均数或者中位数都可以)

通过DataFrame的dropna()、drop()、fillna()方法,可以轻松完成这些操作:

我们先来看一下housing

>>> housing
       longitude  latitude  ...  median_house_value  ocean_proximity
0        -122.23     37.88  ...              452600         NEAR BAY
1        -122.22     37.86  ...              358500         NEAR BAY
2        -122.24     37.85  ...              352100         NEAR BAY
3        -122.25     37.85  ...              341300         NEAR BAY
4        -122.25     37.85  ...              342200         NEAR BAY
          ...       ...  ...                 ...              ...
20635    -121.09     39.48  ...               78100           INLAND
20636    -121.21     39.49  ...               77100           INLAND
20637    -121.22     39.43  ...               92300           INLAND
20638    -121.32     39.43  ...               84700           INLAND
20639    -121.24     39.37  ...               89400           INLAND
[20640 rows x 10 columns]
1.放弃这些相应的地区
>>> housing.dropna(subset=['total_bedrooms']) #option 1
[20433 rows x 10 columns]
2.放弃这个属性
>>> housing.drop('total_bedrooms',axis=1)
[20640 rows x 9 columns]
3.将缺失的值设置为某个值(0、平均数或中位数)
>>> median = housing['total_bedrooms'].median()
housing['total_bedrooms'].fillna(median)
Scikit-Learn imputer

Scikit-Learn提供了imputer来处理缺失值

from sklearn.preprocessing import Imputer
imputer = Imputer(strategy='median')

这里代码发现运行不出来,用的anaconda,这里参考了一下
sklearn.preprocessing里缺失Imputer函数

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy = "mean")
housing_num = housing.drop('ocean_proximity', axis = 1) # 因为中位数只能在数值属性操作 ocean_proximity是object类型
imputer.fit(housing_num)
X = imputer.fit_transform(housing_num)
housing_tr = pd.DataFrame(X, columns= housing_num.columns)

>>> housing_tr
       longitude  latitude  ...  median_income  median_house_value
0        -122.23     37.88  ...         8.3252            452600.0
1        -122.22     37.86  ...         8.3014            358500.0
2        -122.24     37.85  ...         7.2574            352100.0
3        -122.25     37.85  ...         5.6431            341300.0
4        -122.25     37.85  ...         3.8462            342200.0
          ...       ...  ...            ...                 ...
20635    -121.09     39.48  ...         1.5603             78100.0
20636    -121.21     39.49  ...         2.5568             77100.0
20637    -121.22     39.43  ...         1.7000             92300.0
20638    -121.32     39.43  ...         1.8672             84700.0
20639    -121.24     39.37  ...         2.3886             89400.0
[20640 rows x 9 columns]

文本分类

之前排除了分类属性ocean_proximity,因为其是一个文本属性,无法计算它的中位数值。大部分机器学习算法更易于与数字打交道,所以可以先将这些文本标签转化为数字。
Scikit-Learn为这一类任务提供了一个转换器LabelEncoder:

from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
housing_cat=housing['ocean_proximity']
housing_cat_encoded=encoder.fit_transform(housing_cat)
>>> housing_cat_encoded
array([3, 3, 3, ..., 1, 1, 1])

现在可以使用classes_属性来查看这个编码器的映射< 1 H O C E A N 1H OCEAN 对应为 0 0 I N L A N D INLAND 对应为 1 1 >

>>> encoder.classes_
array(['<1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'], dtype=object)

这这种代表方式可能类别0和类别4之间就比类别0和类别1之间的相似度更高
常见的解决方案是给每个类别创建一个二进制的属性,独热编码

from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder()
housing_cat_1hot=encoder.fit_transform(housing_cat_encoded.reshape(-1,1))
>>> housing_cat_1hot
<20640x5 sparse matrix of type '<class 'numpy.float64'>'
	with 20640 stored elements in Compressed Sparse Row format>'

>>> housing_cat_1hot.toarray()
array([[0., 0., 0., 1., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 1., 0.],
       ...,
       [0., 1., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 1., 0., 0., 0.]])

使用LabelBinarizer类可以一次性完成两个转换(从文本类别转化为整数类别,再从整数类别转换为独热向量):

from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer()
housing_cat_1hot = encoder.fit_transform(housing_cat)
>>> housing_cat_1hot
array([[0, 0, 0, 1, 0],
       [0, 0, 0, 1, 0],
       [0, 0, 0, 1, 0],
       ...,
       [0, 1, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 1, 0, 0, 0]])

学习《机器学习实战》,用作笔记。

猜你喜欢

转载自blog.csdn.net/qq_44864262/article/details/107704974