机器学习笔记(一)

作者: Kevin

  • 机器学习经常被看做是人工智能的子领域,但从Data Science应用的角度来看,ML 更应该算是一种建立数据模型的手段,他的本质就是数学及统计学
  • 目前大家说起ML,主要把它归为两类:supervised 和 unsupervised
    • Supervised Learning 主要针对数据的features 和 label 之间的关系进行建模,这其中又可以把它分为 classification 和 regression。简单的理解,classification 针对的是 discrete 的 label;而 regression 则是针对 continuous quantities 的 label
    • Unsupervised Learning 则只是通过数据的features进行建模(数据本身没有label,或者不使用label),也就是“letting the dataset speak for itself”。这其中常见的例如clustering 以及 Dimensionality Reduction。Clustering 主要是通过建模来为数据分群,而Dimensionality Reduction 则是通过建模从高维度数据中发现和找出低维度的结构

Scikit-Learn’s Estimator API

Scikit-Learn 可以说是Python中最出名的ML library 之一,它的特点是 干净、统一以及streamlined API,并且它网上的doc非常丰富,这样的好处是当你学会了其中一种模型的syntax和基本用法,切换到其他模型就非常的简单和容易。

Basics

大致来说 Scikit-Learn estimator API 使用步骤如下:
1. import 一个你想使用的 model class
2. 设置好class 的相应 hyperparameters
3. 将数据分成 features matrix 和 target vector
4. 使用fit() 将模型 fit到已有的数据上
5. 将 model 应用到新的数据上进行预测: 在进行supervised learning时, 我们通常用predict() method 来预测未知数据的label;而unsupervised learning,我们则通常用transform() 或者 predict() 来推测数据的特性


Categorical Data Encoding

现实中,数据中的很多features 不一定会用数字来表示,例如人的性别可以用“男”,“女”,因此我们在做ML时,需要把类似数据转换会机器能理解的类型——数字。

假设我们手上有以下数据

data = [
    {'price': 850000, 'rooms': 4, 'city': 'Downtown Toronto'},
    {'price': 700000, 'rooms': 3, 'city': 'Richmond Hill'},
    {'price': 650000, 'rooms': 3, 'city': 'Waterloo'},
    {'price': 600000, 'rooms': 2, 'city': 'Richmond Hill'}
]

每一条都代表了一幢房子的价格,房间数和所在城市。一开始,我们可能会想说把city 这个column 进行一个简单的 numerical mapping 不就行了,例如以下

{'Downtown Toronto': 1, 'Richmond Hill': 2, 'Waterloo': 3};

但这其实并不是一个很好的approach,因为在Scikit Learn 的模型看来,这意味着 Downtown Toronto < Richmond Hill < Waterloo, 亦或者 Downtown Toronto = Waterloo - Richmond Hill, 而这显然是不合理的。

因此我们可以使用one-hot encoding 的方式来进行mapping。在Scikit Learn 中有很多方法能达到这个目的,例如sklearn.preprocessing.OneHotEncodersklearn.feature_extraction.FeatureHasher,以及sklearnfeature_extraction.DictVectorizer。因为上面的数据是dict的形式,所以这里我们用DictVectorizer来做示范:

from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer(sparse=False, dtype=int)
vec.fit_transform(data)

output:
array([[     1,      0,      0, 850000,      4],
       [     0,      1,      0, 700000,      3],
       [     0,      0,      1, 650000,      3],
       [     0,      1,      0, 600000,      2]], dtype=int64)
vec.get_feature_names()

output:
['city=Downtown Toronto',
 'city=Richmond Hill',
 'city=Waterloo',
 'price',
 'rooms']

整个数据多出了两列,这是因为原来‘city’ column 中一共有3类categorical data,因此每一个分别对应一列,而原本的‘city’ 则被删去。每一column中的1则对应原本每一row中 city 的值。
当然这种方法有一个缺点,如果你的categorical feature 有很多可能的值(例如1000个不同的城市)那dataset size 也会变的非常大,很有可能memory就会放不下。这时候我们可以发挥sparse matrix的优势——只记录非0值的位置。

vec = DictVectorizer(sparse=True, dtype=int)
vec.fit_transform(data)

output:
<4x5 sparse matrix of type 'numpy.int64'>'
    with 12 stored elements in Compressed Sparse Row format>

处理缺失数据

我们经常见到在 Dataframe 中 缺失值以 NaN 来 mask,而当我们想要使用含缺失值的dataset来做ML时,第一步就需要想办法将缺失值进行填补。

from numpy import nan
X = np.array([[ nan, 0,   3  ],
              [ 3,   7,   9  ],
              [ 3,   5,   2  ],
              [ 4,   nan, 6  ],
              [ 8,   8,   1  ]])

填补的手段有很多,从最简单的使用column的mean,到更复杂的matrix completion。这个需要根据情况而定。

如果我们只想使用最基础的填补方法(mean. median, most freq value,etc.),Scikit-Learn 提供了 Imputer class:

from sklearn.preprocessing import Imputer
imp = Imputer(strategy='mean')
X2 = imp.fit_transform(X)
X2

output:
array([[ 4.5,  0. ,  3. ],
       [ 3. ,  7. ,  9. ],
       [ 3. ,  5. ,  2. ],
       [ 4. ,  5. ,  6. ],
       [ 8. ,  8. ,  1. ]])

模型认证

认证模型准确度的时候,千万不能犯的错误就是训练和认证都使用同一dataset。正确的方式应该是将dataset 分割成training 和 testing,我们可以使用train_test_split 来对dataset 进行 分割:

假设 X 为 dataset,y为 X 的 label

from sklearn.cross_validation import train_test_split

# 我们可以调整 train_size 来改变分割的比例,这里0.5 就代表 各50%
X1, X2, y1, y2 = train_test_split(X, y, random_state=0,
                                  train_size=0.5)

# 将模型应用到training set 上
model.fit(X1, y1)

# 使用 testing set 对 模型准确度进行认证
y2_model = model.predict(X2)
accuracy_score(y2, y2_model)

将dataset 分割的缺点是我们因此损失了一部分可用的训练数据,那么则很有可能失去一部分数据的特性,因此还有一种approach 就是使用 cross-validation:也就是对model进行一系列的fits,每次fit 都使用不同的分割方式,具体思路如下图
机器学习笔记(一)_第1张图片

机器学习笔记(一)_第2张图片
假如我们想进行更多次的cross-validation 的话,就可以用到 cross_val_score

cross_val_score(model, X, y, cv=5)

output:
array([ 0.96666667,  0.96666667,  0.93333333,  0.93333333,  1.        ])

Reference

Python Data Science Handbook by Jake VanderPlas
https://github.com/jakevdp/PythonDataScienceHandbook

个人强烈推荐的入门数据分析的一本好书

你可能感兴趣的:(大数据,python,机器学习)