1. 什么是机器学习?
让机器根据用户的输入来寻找规律,而无需进行显示的编程,同时可以根据用户的输入不断的调整从而进行更精准的预测。
2. 机器学习分类:
2.1 有监督学习
在训练集中,每个样本都有明确的目标值或标签。
应用:分类和回归。
分类:数字识别,判断天气是否有雨。
回归:放假预测等。
2.2 无监督学习
没有给定的目标值或者标签。(需要模型自己发现数据结构和规律)
应用:聚类和降维。(没有明显的特征
聚类:将相似特征的点,归为一类。
降维:降低原来的数据特征,并尽可能的保留原始的数据特征,减少计算的复杂度。常见的降维有:主成分分析,线性判别法等。
应用场景:异常检测:根据用户的消费习惯,来分析用户的某一笔消费是否是异常消费。
3. 机器学习基本步骤
1. 加载数据
2. 数据预处理
3. 选择模型
4. 训练模型
5. 评估模型:根据方差或者模型提供的函数来对模型进行评价。
6. 调整参数
7. 预测新数据
4. KNN算法简介:
4.1 简单介绍
KNN算法是一种简单而有效的监督学习算法,适用于分类和回归任务。根据点之间的距离,来对节点进行判断。
那么问题来了:
1. K的选择?
2. 举例的度量?怎么算距离
3. 权重:不同的点权重是否一致。
4. 不同的特征,可能如身高,体重差异较大,应该怎么处理?
4.2 KNN算法优缺点
优点:简单,直观。
缺点:
1. 计算量大,因为每个待分类样本都需要计算与所有点之间的距离。
2. K值的选择对模型的影响比较大。
3. 存储需求高:需要存储所整个训练集,存储需求较大。
KNN算法计算量较大,对大型数据集的处理效率较低,所以在实际应用中,数据量不能过大。
K值的影响:
K值过大:模型简单,决策边界更加平滑,而不是不规则和碎片化。
K值过小:模型复杂,对噪声和异常值敏感。
4.3 代码实战:
机器中,最常用的算法库是sklearn,下面单独讲解sklearn关于KNN的建模使用。
1. 引入模型:在neighbors库中
2. model的参数详解:(自己的理解,最常用的参数)
model = KNeighborsClassifier();
1. n_neighbor: 邻居的数量,默认是5
2. weights: 度量方式, 可以是 'uniform' -- 权重一样
'distance' -- 权重为 距离的倒数
3. p: 距离计算: 1 -- 曼哈顿距离,2--欧氏距离
3. GridSearchCV: 网格搜索,交叉验证
1. estimator: 我们需要估计的模型
2. param_grid: 字典,对于上述模型,我们需要优化哪些参数
3. scoring: 模型评分,我们应该怎么对模型的好坏进行判断。
1. 如果是分类的话,可以简单的使用 'accuracy' 表示准确率
2. 如果是回归的话,可以简单的使用 'neg_mean_squared_error' 表示方差
4. cv: 交叉验证的时候,划分的份数
4. 后面有更高效的搜索方式:RandomizedSearchCV 。 其实用法和上面都是一样的。
4.3.1 鸢尾花分类(使用SKlearn)
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def test01():
# 1. 记载数据集
X, y = load_iris(return_X_y=True)
# 2. 拆分数据集
# 分为训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 3. 选择模型/建立模型
model = KNeighborsClassifier(n_neighbors=3)
# 4. 进行训练
model.fit(x_train, y_train)
# 5. 进行预测
score = model.score(x_test, y_test)
print(score)
4.3.2 优化
根据上面的思考,由于影响模型的参数有很多,比如K值的选择,距离的度量(使用曼哈顿距离还是欧氏距离),权重的选择。所以我们不能单纯的自己决定使用哪些参数,而应该经过计算,选择出来在训练集上的最优参数。 GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV # 网格搜索,交叉验证
import numpy as np
def test02():
# 1. 加载数据
X, y = load_iris(return_X_y=True)
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
# 2. 建模
model = KNeighborsClassifier()
# 3. 模型优化,下面的三个参数,是model需要优化的参数
neighbors = np.arange(1, 15)
weights = ['uniform', 'distance']
p = [1, 2]
param = {'n_neighbors': neighbors, 'weights': weights, 'p': p}
# 4. 进行网格搜索
gcv = GridSearchCV(estimator=model, param_grid=param, scoring='accuracy', cv=5)
gcv.fit(x_train, y_train)
print(gcv.best_params_)
print(gcv.score(x_test, y_test))
4.3.3 KNN线性回归
from sklearn.neighbors import KNeighborsRegressor
from sklearn.datasets import fetch_california_housing # 403 forbidden
import pandas as pd
def test03():
# 使用KNN进行线性回归分析
data_url = "http://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data"
df = pd.read_csv(data_url, header=None, sep='\s+')
print(df.shape)
X = df.iloc[:, :-1].values
y = df.iloc[:, -1].values
# print(X.shape, y.shape)
# 开始进行数据的分割
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 进行参数优化
neighbors = np.arange(1, 15)
weights = ['uniform', 'distance']
p = [1, 2]
param = {'n_neighbors': neighbors, 'weights': weights, 'p': p}
model = KNeighborsRegressor()
# 其实跟KNN的分类是一样的,除了对于误差的衡量,scoring不同
gcv = GridSearchCV(estimator=model, param_grid=param, scoring='neg_mean_squared_error', cv=5)
gcv.fit(x_train, y_train)
print(gcv.score(x_test, y_test))
4.3.4 归一化、标准化提高准确率
由于在很多情况下,数据的差异相对较大,所以我们需要进行数据的统一之后,方便我们进行预测,也就是数据的预处理。
其实很多情况下,数据的预处理有,去除异常值,填补空值等。其实在机器学习中,前置的数据预处理是非常重要的一步,很大程度上关系着我们模型的训练效果。
# 回归优化,进行归一化和标准化
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# 在此处使用standardScaler进行归一化
import pandas as pd
def test04():
# 在进行归一化的时候,只需要对X进行归一化,而不需要对y进行归一化。这是一定的
# 在很多情况下,归一化的效果是要好于最大最小值归一化的。
data = pd.read_csv("./cancer.csv", sep="\t")
# print(data.head())
datay = data["Diagnosis"]
dataX = data.iloc[:, 2:].values
# 进行minMax归一化
# minMaxScaler = MinMaxScaler()
# dataX = minMaxScaler.fit_transform(dataX)
# 使用standardScaler进行归一化
standardizer = StandardScaler()
dataX = standardizer.fit_transform(dataX)
# 开始进行训练
x_train, x_test, y_train, y_test = train_test_split(dataX, datay, test_size=0.2, random_state=42)
model = KNeighborsClassifier()
neighbors = np.arange(1, 15)
weights = ['uniform', 'distance']
p = [1, 2]
param = {'n_neighbors': neighbors, 'weights': weights, 'p': p}
gcv = GridSearchCV(estimator=model, param_grid=param, scoring='accuracy', cv=5)
gcv.fit(x_train, y_train)
# print(gcv.best_params_)
print(gcv.score(x_test, y_test))
4.3.5 标签数据化,归一化,去除异常数据(使用置信区间)
# 将不同的数据类型转换为数字数据
# 在我们的处理过程中,通常有很多的数据是非数值类型的,这个时候我们需要将数据进行数值化。
# 非数值类型转换为数值类型, labelEncoding
# 使用标准差的方式对数据进行过滤
from sklearn.preprocessing import LabelEncoder
def test05():
# 1. 读取数据
data = pd.read_csv("./adults.txt")
print(data.head())
X = data.iloc[:, :-1]
y = data.iloc[:, -1].values
# 首先进行数据处理
non_numeric_columns = X.select_dtypes(exclude=[np.number]).columns
# print(non_numeric_columns)
# 对这些列进行处理
le = LabelEncoder()
for col in non_numeric_columns:
X[col] = le.fit_transform(X[col])
print(X.head())
# 处理空值
X = X.dropna(axis=0)
print(X.shape)
# 根据标准分布,去除掉在置信区间之外的数据
for col in X.columns:
mean = X[col].mean()
std = X[col].std()
lowerBound = mean - 3 * std;
upperBound = mean + 3 * std;
X = X[(X[col] >= lowerBound) & (X[col] <= upperBound)]
# 筛选完成 -- 到这里才发现,其实也要对y进行同样的筛选。直接把x的索引拿过来用了
print(X.shape)
y = y[X.index]
# 标准化
standardizer = StandardScaler()
X = standardizer.fit_transform(X)
# 所有数据处理完毕,后面的训练过程就基本一样了
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = KNeighborsClassifier()
neighbors = np.arange(1, 15)
weights = ['uniform', 'distance']
p = [1, 2]
param = {'n_neighbors': neighbors, 'weights': weights, 'p': p}
gcv = GridSearchCV(estimator=model, param_grid=param, scoring='accuracy', cv=5)
gcv.fit(x_train, y_train)
print(gcv.best_params_)
print(gcv.score(x_test, y_test))