上一篇讲了基本的端到端项目开发的起步,本篇将要更加详细的讲解开发机器学习项目的其他重点。

1.获取数据(续)

上篇了解了pandas的两种数据结构Series和DataFrame,以及使用urllib下载数据文件和初步查看数据,现在讲解如何更加详细的查看和分析数据。

1.1 快速查看数据结构

注:我们已经通过fetch_housing_data()和load_housing_data()两个函数从远程服务器上下载了h服务器租用ousing.csv测试抑郁症,并将其缓存到Dataframe类型的housing中服务器怎么搭建

虽然相比其他的机器学习项目,本次的housing数据并不是很多。如果我们python是什么意思是直接输出查看也还是很困难的。但是我们可以使用Dpython怎么读ataFrame的head()和tail()查看前几行数据或者后几行数据。

housing = load_housing_data()
housing.head(5)
housing.tail(5)
# 输出
       longitude  latitude  ...  median_house_value  ocean_proximity
0        -122.23     37.88  ...            452600.0         NEAR BAY
1        -122.22     37.86  ...            358500.0         NEAR BAY
2        -122.24     37.85  ...            352100.0         NEAR BAY
3        -122.25     37.85  ...            341300.0         NEAR BAY
4        -122.25     37.85  ...            342200.0         NEAR BAY
[5 rows x 10 columns]
       longitude  latitude  ...  median_house_value  ocean_proximity
20635    -121.09     39.48  ...             78100.0           INLAND
20636    -121.21     39.49  ...             77100.0           INLAND
20637    -121.22     39.43  ...             92300.0           INLAND
20638    -121.32     39.43  ...             84700.0           INLAND
20639    -121.24     39.37  ...             89400.0           INLAND
[5 rows x 10 columns]
# FrameOrSeries.head(n) 的作用就是返回当前调用的DataFrame或Series的前n行
# FrameOrSeries.tail(n) 的作用则是返回当前调用的DataFrame或Series的后n行

注意:如果读者的服务器内存和台式机内存区别开发环境是jupyter noteb服务器系统ook,则只需要housing.head(5)/housing.tail(5),点击运行便可以直接获得输出。如果使用的是PyCharm,则需要使用print服务器价格(housing.head(5))函数进行输出。

同时我们还知道了其所有的columns也就是housing有哪些属性,但是如果我们想要更加查看housing的更多信息,就需要用info算法是指什么()来获取数据集的简单描述。

housing.info()
# 输出信息:
# 1. class类型
<class 'pandas.core.frame.DataFrame'>
# 2. 获得总行数
RangeIndex: 20640 entries, 0 to 20639
# 3. 获取每个属性的类型和是否非空
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  float64 #房龄中位数
 3   total_rooms         20640 non-null  float64 #总房间
 4   total_bedrooms      20433 non-null  float64 #总卧室
 5   population          20640 non-null  float64 #区域人口
 6   households          20640 non-null  float64 #区域家庭
 7   median_income       20640 non-null  float64 #收入中位数
 8   median_house_value  20640 non-null  float64 #房价中位数
 9   ocean_proximity     20640 non-null  object  #与海的空间关系
dtypes: float64(9), object(1)
# 4.获取总内存
memory usage: 1.6+ MB
None

这里我们需要注意一点,total_bedrooms的非空值比其他属approve性要少207个区域,因此在此服务器系统后的处理需要考虑到该问题。

我们使用info()知道了hoappetiteusing下有10个属性,但是其中一个是object,如果在python下,则可能是任何对象,但是我们是从csv下加载的apple,所以只可能是文本属性服务器算法分析的目的是我们可以使用value_counts() 方法,去了解该属下将地理区域分成了什么。

housing["ocean_proximity"].value_counts()
# 输出
<1H OCEAN     9136 # 到海洋小于1小时
INLAND        6551 # 陆地
NEAR OCEAN    2658 # 海洋附近
NEAR BAY      2290 # 海湾附近
ISLAND           5 # 岛屿
Name: ocean_proximity, dtype: int64

如果我们还想要继续python安装教程做一些简单的测试手机是否被监控统计,比如获得总行(count)、平均值(mean)、标准差(std:用于测量数值的离散程度)等等,我们还可以通过describe() 方法。

housing.describe()
# 输出8种统计
          longitude      latitude  ...  median_income  median_house_value
count  20640.000000  20640.000000  ...   20640.000000        20640.000000 # 统计总数、不统计空值
mean    -119.569704     35.631861  ...       3.870671       206855.816909 # 平均值
std        2.003532      2.135952  ...       1.899822       115395.615874 # 标准差
min     -124.350000     32.540000  ...       0.499900        14999.000000 # 最小值
25%     -121.800000     33.930000  ...       2.563400       119600.000000 # 第25分位/第一四分位
50%     -118.490000     34.260000  ...       3.534800       179700.000000 # 第50分位
75%     -118.010000     37.710000  ...       4.743250       264725.000000 # 第75分位/第三四分位
max     -114.310000     41.950000  ...      15.000100       500001.000000 # 最大值
[8 rows x 9 columns]

我们还能够借助matplotlib画housing直方图,所用的函数就是hist(),hist()可以画出housing每个数值类型属性的直方图(x轴是属性值的范围,y轴是实例的数量)。

housing.hist(bins=50, figsize=(20, 15))
plt.show()

端到端机器学习项目-加州房价预测(二)

图1.1 每个数值属性的直方图服务器内存条可以用在台式机上吗

直方图能够更加直观的告诉我们服务器是什么如下内容:

  1. 收入的单位可能不是美元,事实也是如python123平台登录此,单位是万美元。且可以看出含有上下界,0.5-15万美元之间。
  2. 房龄中位数和房价中位数,也被设置了上限。而且是很大的问题,之后读者若是遇见,则需要和客户或者负责人搞清楚,是否会存在房价大于当前的上限,测试用例以防出现过高的房价被误判成错误数服务器内存和台式机内存区别据。遇见此类,一般的解决方法如下:
    • 需要对设置上限的数据重新收集
    • 或者将服务器操作系统设置上限的区域数据从训练集移除(以防将测试集内的服务器是什么高房价评估为不良)
  3. 这些属性值的缩放不同
  4. 有些直方图出现重尾,这对某些机器学算法的特征算法难以检测出模型来,因此后面将需要一些转化方法,将其变成类似钟形appointment的分布。

1.2 创建测试集

在金融分析里有一个非常普遍和严重的问题叫数据测试抑郁症的20道题窥探偏测试抑郁程度的问卷(data snooping bias),这个问题是指发现数据统计上有着显著的关系,但是实际并不存在的关系。比如给与足够的时间去统计一个数据集,我们可appear能推出任何的规律,然而实际却是无用的规律,而这些错误的规律一旦建立成模型,那么依据该模型推测的结果也是错误的。

因此在划分训练集时,应当要保证每次执行程序时分割的测试抑郁症的20道题训练集和算法测试集都应当是一致的,不然不同的训练集下训练来出来的模型将会有各种可能,导致测试的时候效果很好,但是泛化时却效果不够预测的优秀。

# 一个简单的分割函数,可以按照test_ration划分
# np.random.permutation(len(data)) 可以根据现有的housing的数据长度,随机的生成各种序列
def split_train_test(data, test_ratio):
    shuffled_indices = np.random.permutation(len(data))
    test_set_size = int(len(data) * test_ratio)
    train_indices = shuffled_indices[test_set_size:]
    test_indices = shuffled_indices[:test_set_size]
    return data.iloc[train_indices], data.iloc[test_indices]

使用split_traappreciatein_test(housing, 0,2),我们可以轻松获得拥有housinapproveg的随机80%数据的训练集和20%的测试集。但是这个函数,问题很明显,那就是随机不可控,如果下次重新运行,训练集和测试集有将会不同,这算法的时间复杂度取决于是存在巨大的问python可以做什么工作题的:如果足够次数的重新运行,训练集就迟早变成全部数据集。一般的处理方式:

  1. 我们可以提前保存首次分割的数据,之后的运行只需要加载就行
  2. 因为appearnp.random.permuta测试抑郁症tion()使用的是伪appearance随机,可以通过设置np.randpython123om.se测试英文ed(42)保证每一次生成的序列是一致的

这只能保python可以做什么工作证数据源不增加的前提,但是如果新增服务器系统数据后,这两个解决方案还是有不足的。因此最好的方案还是给每一个数据,都能够生成一个独一无二的标识符(identifier),再通过hash算法,将每一个数据都能固定放入训练集或者测试集中,无论是否有新增,都算法的有穷性是指不会产生影响。

from zlib import crc32
# 比较常用的检测算法
# crc32(np.int64(identifier)) & 0xffffffff 会返回小于 2 ** 32的无符号数
# crc32在python3 下返回为无符号,通过 0xffffffff 的 &运算,保证python2和python3 返回一致数
def test_set_check(identifier, test_ratio):
    return crc32(np.int64(identifier)) & 0xffffffff < test_ratio * 2 ** 32
# 通过test_set_check()和id_column字段可以分割出train_set和test_set
def split_train_test_by_id(data, test_ratio, id_column):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio))
    # print(in_test_set)
    return data.loc[~in_test_set], data.loc[in_test_set]

housing没有定义好的标识符,但是可以通过索引当作一个标识符

# housing.set_index()会重置每一行的index,并且生成新的"index"列
hosing_witd_id = housing.set_index()
train_set, test_set= split_train_test_by_id(housing_with_id, 0,2, 'index')

使用索引作为标识符,需要特别注意不能删除数据,且只能在末尾添加新数据,否则就不能唯一标识数据。如果算法不能保证这两点,还可以使用housing中很稳定的两个属性经度和纬度。


hosing_witd_id['id'] = housing.['longitude']* 1000 + housing['latitude']
train_set, test_set= split_train_test_by_id(housing_with_id, 0,2, 'id')

当然也可以直接使用Scikit-Learn提供的算法工程师一个分割方法appeartrain_test_spilt(),他也可以传入randopython保留字m_state,用python基础教程于设置随机数种子,且如果同时有多个数据集,他也能够按照唯一的索引进行分割。

from sklearn.model_selection important spilt_train_test
train_set, test_set = spilt_train_test(housing, test_size=0.2, randon_state=42)

ok,到目前为止讲了很多的分割训练集和测试集的方法,但是我们也发现了一个问题,那就是这些都是纯随机的分割,那么这样的分割是否符合完整数据集的数据分布,或者说还有没有方法能够让分割的数据集更加符合完整的python可以做什么工作数据集的分布律?