机器学习介绍/K-NN最近邻

一、机器学习介绍

(一)什么是机器学习

机器学习就是把无序的数据转换成有用的信息。

(二)术语

特征或者属性通常是训练样本集的列,它们是独立测量得到的结果,多个特征联系在一起共同组成一个训练样本。机器学习的主要任务就是分类。通常为算法输入大量已分类数据作为算法的训练集。为了测试机器学习算法的效果,通常使用两套独立的样本集:训练数据和测试数据。

(三)机器学习的任务

机器学习的另一项任务是回归,它主要用于预测数值型数据。分类和回归属于监督学习,之所以称之为监督学习,是因为这类算法必须知道预测什么,即目标变量的分类信息。与监督学习相对应的是无监督学习,此时数据没有类别信息,也不会给定目标值。在无监督学习中,将数据集合分成由类似的对象组成的多个类的过程被称为聚类;将寻找描述数据统计值的过程称之为密度估计。

(四)如何选择算法

首先考虑使用机器学习算法的目的。如果想要预测目标变量的值,则可以选择监督学习算法,否则可以选择无监督学习算法。确定选择监督学习算法之后,需要进一步确定目标变量类型,如果目标变量是离散型,如是/否、1/2/3、A/B/C或者红/黄/黑等,则可以选择分类器算法;如果目标变量是连续型的数值,如0.0~100.00、-999~999或者+∞~-∞等,则需要选择回归算法。如果不想预测目标变量的值,则可以选择无监督学习算法。进一步分析是否需要将数据划分为离散的组。如果这是唯一的需求,则使用聚类算法;如果还需要估计数据与每个分组的相似程度,则需要使用密度估计算法。

其次需要考虑的是数据问题。主要应该了解数据的以下特性:特征值是离散型变量还是连续型变量,特征值中是否存在缺失的值,何种原因造成缺失值,数据中是否存在异常值,某个特征发生的频率如何(是否罕见得如同海底捞针),等等。充分了解上面提到的这些数据特性可以缩短选择机器学习算法的时间。

(五)开发步骤

扫描二维码关注公众号,回复: 6754868 查看本文章

使用机器学习算法开发应用程序,通常遵循以下的步骤。(1) 收集数据。(2) 准备输入数据。(3) 分析输入数据。(4) 训练算法。(5) 测试算法。(6) 使用算法。

(六)实战:通过投放广告的金额预测销售额

1.收集、准备数据

你所在的公司在电视上做产品广告, 收集到了电视广告投入x(以百万为单位)与产品销售量y(以亿为单位)的数据. 你作为公司的数据科学家, 希望通过分析这些数据, 了解电视广告投入x(以百万为单位)与产品销售量y的关系。假设x与y的之间的关系是线性的, 也就是说 y = ax + b. 通过线性回归(Linear Regression), 我们就可以得知 a 和 b 的值. 于是我们在未来做规划的时候, 通过电视广告投入x, 就可以预测产品销售量y, 从而可以提前做好生产和物流, 仓储的规划. 为客户提供更好的服务。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

data = pd.read_csv("data/Advertising.csv")

 2.分析数据

data.head()

data.columns

data.info()
RangeIndex: 200 entries, 0 to 199
Data columns (total 2 columns):
TV       200 non-null float64
sales    200 non-null float64
dtypes: float64(2)

TV为特征,连续型的数值。sales为标签,连续性数值,因此选择回归算法。做出散点图,观察数据发现数据呈现出现行关系,因此选择线性回归。

plt.figure(figsize=(16, 8))
plt.scatter(data['TV'], data['sales'], c ='black')
plt.xlabel("Money spent on TV ads")
plt.ylabel("Sales")
plt.show()

3.训练、测试算法

X = data['TV'].values.reshape(-1,1)
y = data['sales'].values.reshape(-1,1)

reg = LinearRegression()
reg.fit(X, y)

print('a = {:.5}'.format(reg.coef_[0][0]))
print('b = {:.5}'.format(reg.intercept_[0]))

print("线性模型为: Y = {:.5}X + {:.5} ".format(reg.coef_[0][0], reg.intercept_[0]))
a = 0.047537
b = 7.0326
线性模型为: Y = 0.047537X + 7.0326 

predictions = reg.predict(X)

plt.figure(figsize=(16, 8))
plt.scatter(data['TV'], data['sales'], c ='black')
plt.plot(data['TV'], predictions,c ='red', linewidth=2)
plt.xlabel("Money spent on TV ads")
plt.ylabel("Sales")
plt.show()

4.使用算法

predictions = reg.predict([[100]])
print('投入一亿元的电视广告, 预计的销售量为{:.5}亿'.format( predictions[0][0]) )

投入一亿元的电视广告, 预计的销售量为11.786亿 。

(七)作业:预测海拔高度和气温的关系

气温会随着海拔高度的升高而降低, 我们可以通过测量不同海拔高度的气温来预测海拔高度和气温的关系。我们假设海拔高度和气温的关系可以使用如下公式表达:y(气温) = a * x(海拔高度) + b。理论上来讲, 确定以上公式 a 和 b的值只需在两个不同高度测试, 就可以算出来 a 和 b 的值了. 但是由于所有的设备都是有误差的, 而使用更多的高度测试的值可以使得预测的值更加准确. 我们提供了在9个不同高度测量的气温值, 请你根据今天学习的线性回归方法预测 a 和 b 的值. 根据这个公式, 我们预测一下在8000米的海拔, 气温会是多少?

1.收集、准备数据

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

data = pd.read_csv("exercise/height.vs.temperature.csv")

 2.分析数据

data.info()
Data columns (total 2 columns):
height         9 non-null float64
temperature    9 non-null float64
dtypes: float64(2)
plt.figure(figsize=(16,8))
plt.scatter(data['height'],data['temperature'],c='black')
plt.xlabel("Height")
plt.ylabel("Temperature")
plt.show()

 3.训练、测试算法

X=data['height'].values
X

X=data['height'].values.reshape(-1,1)
X

y=data['temperature'].values
y

y=data['temperature'].values.reshape(-1,1)
y

reg = LinearRegression()
reg.fit(X,y)

print('a={:.5}'.format(reg.coef_[0][0]))
print('b={:.5}'.format(reg.intercept_[0]))

predictions = reg.predict(X)
plt.figure(figsize=(16,8))
plt.scatter(data['height'],data['temperature'],c='black')
plt.plot(data['height'],predictions,c='b',linewidth=2)
plt.xlabel("Height")
plt.ylabel("Temperature")
plt.show()

 

4.使用算法

predictions = reg.predict([[8000]])
print('在8000米的海拔, 气温会是{:.5}。'.format( predictions[0][0]))

在8000米的海拔, 气温会是-39.838。
 

二、K-NN最近邻

(一)算法概述

k-近邻算法采用测量不同特征值之间的距离方法进行分类。存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

k-近邻算法的一般流程:(1) 收集数据:可以使用任何方法。(2) 准备数据:距离计算所需要的数值,最好是结构化的数据格式。(3) 分析数据:可以使用任何方法。(4) 训练算法:此步骤不适用于k-近邻算法。(5) 测试算法:计算错误率。(6) 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。

(二)实战:使用k-近邻算法预测市场中二手车的价格

1.收集、准备数据

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv('data.csv')

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

2.分析数据

data.head()
data.info()

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

RangeIndex: 13 entries, 0 to 12
Data columns (total 8 columns):
Brand                13 non-null object
Type                 13 non-null float64
Color                13 non-null object
Construction Year    13 non-null int64
Odometer             13 non-null int64
Ask Price            13 non-null int64
Days Until MOT       13 non-null int64
HP                   13 non-null int64
dtypes: float64(1), int64(5), object(2)

Brand、Type、Color、Construction Year、Odometer、Days Until MOT、HP为特征,其中,Brand、Type、Color为离散型数值,Construction Year、Odometer、Days Until MOT、HP为连续型的数值。Ask Price为标签,为连续性数值,因此选择回归算法。

y = data['Ask Price']
y
X = data.drop(['Ask Price'],axis=1)
X.columns

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

观察数据可知,Brand列为相同的值,可以将其删除。Type、Color为离散型数值,在机器学习中,大多数算法,譬如逻辑回归,支持向量机SVM,k近邻算法等都只能够处理数值型数据,不能处理文字。在这种情况下,为了让数据适应算法和库,必须将数据进行编码,将文字型数据转换为数值型。Type、Color为名义变量,即变量之间是相互独立的,彼此之间完全没有联系,通过使用哑变量的方式来处理,才能够尽量向算法传达最准确的信息。Construction Year、Odometer、Days Until MOT、HP为连续型的数值。在距离类模型,譬如k近邻,K-Means聚类中,无量纲化可以提升模型精度,避免某一个取值范围特别大的特征对距离计算造成影响。因此将Construction Year、Odometer、Days Until MOT、HP的数据进行标准化处理。

from sklearn.preprocessing import OneHotEncoder

X1 = X.iloc[:,1:3]
X1.head()

ohe = OneHotEncoder()
X2 = ohe.fit_transform(X1).toarray()
X2

ohe.get_feature_names()

from sklearn.preprocessing import StandardScaler

X

X3 = X.iloc[:,3:]
X3.columns

scaler = StandardScaler()
X4 = scaler.fit_transform(X3)

X6 = pd.concat([pd.DataFrame(X2),pd.DataFrame(X4)],axis=1)
X6

X6.columns = [ 'x0_1.0', 'x0_1.1', 'x0_1.4', 'x1_black', 'x1_blue', 'x1_green',
       'x1_grey', 'x1_red', 'x1_white','Construction Year','Odometer', 'Days Until MOT','HP']
X6

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

原始数据有8个特征,减掉Brand特征,增加前面独热编码生成的特征,新的数据有13个特征。为了让算法运算更快,效果更好,使用PCA(主成分分析)算法对数据进行降维,即降低特征矩阵中特征的数量。

from sklearn.decomposition import PCA

X6.shape

#调用PCA
pca = PCA(n_components=2) #实例化
pca = pca.fit(X6) #拟合模型
X_dr = pca.transform(X6) #获取新矩阵
X_dr

pca.explained_variance_
pca.explained_variance_ratio_
pca.explained_variance_ratio_.sum()
pca.explained_variance_
pca.explained_variance_ratio_
pca.explained_variance_ratio_.sum()

pca_line = PCA().fit(X6)
plt.plot(list(range(13)),np.cumsum(pca_line.explained_variance_ratio_))
plt.xticks(list(range(13))) #这是为了限制坐标轴显示为整数
plt.xlabel("number of components after dimension reduction")
plt.ylabel("cumulative explained variance ratio")
plt.show()

pca = PCA(n_components=4)
X_dr = pca.fit_transform(X6)
X_dr

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

3.训练、测试算法

from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X6,y,random_state=0)

X_train

X_test

y_train

knn = KNeighborsRegressor(n_neighbors=2)
knn.fit(X_train,y_train)

result = knn.predict(X_test)

result

y_test

plt.scatter(result, y_test)
diagonal = np.linspace(500, 1500, 100)
plt.plot(diagonal, diagonal, '-r')
plt.xlabel('Predicted ask price')
plt.ylabel('Ask price')
plt.show()

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

在回归类算法中,有两种不同的角度来看待回归的效果:第一,我们是否预测到了正确的数值。均方误差,本质是在RSS的基础上除以了样本总量,得到了每个样本量上的平均误差。有了平均误差,就可以将平均误差和标签的取值范围在一起比较,以此获得一个较为可靠的评估依据。

第二,我们是否拟合到了足够的信息。对于回归类算法而言,只探索数据预测是否准确是不足够的。除了数据本身的数值大小之外,我们还希望我们的模型能够捕捉到数据的”规律“,比如数据的分布规律,单调性等等,而是否捕获了这些信息并无法使用MSE来衡量。如果一条曲线前半部分的拟合非常成功,真实标签和我们的预测结果几乎重合,但后半部分的拟合却非常糟糕,模型向着与真实标签完全相反的方向去了。对于这样的一个拟合模型,如果使用MSE来对它进行判断,它的MSE会很小,因为大部分样本其实都被完美拟合了,少数样本的真实值和预测值的巨大差异在被均分到每个样本上之后,MSE就会很小。但这样的拟合结果必然不是一个好结果,因为一旦新样本是处于拟合曲线的后半段的,预测结果必然会有巨大的偏差,而这不是我们希望看到的。所以,除了判断预测的数值是否正确之外,还能够判断我们的模型是否拟合了足够多的,数值之外的信息。为了衡量模型对数据上的信息量的捕捉,我们定义R^{^{2}}来帮助我们:方差的本质是任意一个值和样本均值的差异,差异越大,这些值所带的信息越多。R^{^{2}}越接近1越好。

from sklearn.metrics import mean_squared_error, r2_score

# 均方误差
print("Mean squared error: %.2f" % mean_squared_error(y_test, result))
# 方差分数: 1代表完美预测
print('Variance score: %.2f' % r2_score(y_test, result))

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

Mean squared error: 54294.12
Variance score: 0.66

从均方误差和方差的结果来看,模型预测的效果不太好。

猜你喜欢

转载自blog.csdn.net/weixin_42295205/article/details/94125881
今日推荐