数据集的构成:特征值+目标值
机器学习算法分类:
监督学习:有目标的
目标值:类别---分类问题
目标值:连续型的数据---回归问题
无监督学习:
目标值:无
机器学习开发流程
- 获取数据
- 数据处理
- 特征工程
- 机器学习算法训练 –模型
- 模型评估
- 应用
sklearn 数据集使用
pip install sklearn
- sklearn.datasets
- 加载获取流行数据集
- datasets.load_*()
- 获取小规模数据集
- datasets.fetch_*(data_home=None)
- 获取大规模数据集,需要从网络上下载
sklearn 小数据集
- sklearn.datasets.load_iris()
加载并返回鸢尾花数据集
sklearn大数据集
- sklearn.datasets.fetch_20newsgroups(data_home=None,subset=’train’)
数据集的返回值
datasets.base.Bunch(继承自字典)
dict['key'] = values
bunch.key=values
data:特征数据数组
target:标签数组
DESCR:数据描述
feature_names:特征名
target_names:标签名
from sklearn.datasets import load_iris
def datasets_demo():
"""
sklearn数据集使用
:return:
"""
#获取数据集
iris = load_iris()
print("鸢尾花数据集的返回值:\n",iris)
print("查看数据集描述:\n",iris['DESCR'])
print("查看特征值的名字:\n",iris.feature_names)
print("查看目标值名字:\n",iris.target_names)
return None
if __name__ =="__main__":
datasets_demo()
数据集的划分:一部分训练,一部分测试 测试集一般占20-30%
数据集划分api : from sklearn.model_selection import train_test_split
- x数据集的特征值
- y数据集的标签值
- test_size测试集的大小,一般为float
- random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
- return 训练集特征值,测试集特征值,训练集目标值,测试集目标值
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def datasets_demo():
"""
sklearn数据集使用
:return:
"""
# 获取数据集
iris = load_iris()
print("鸢尾花数据集的返回值:\n", iris)
print("查看数据集描述:\n", iris['DESCR'])
print("查看特征值的名字:\n", iris.feature_names)
print("查看目标值名字:\n", iris.target_names)
# 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
print("训练集的特征值:\n", x_train, x_train.shape)
return None
if __name__ == "__main__":
datasets_demo()
1.特征提取
sklearn.feature.extraction
将任意数据(文本或图像)转换为可用于机器学习的数字特征
- 字典特征提取:类别->one-hot编码
sklearn.feature.extraction.DictVectorizer(sparse=True)
返回sparse矩阵(稀疏矩阵) 将非0值按位置表示出来,节省内存,提高加载效果 - 文本特征提取 :单词作为特征
方法1:CountVectorizer 统计每个样本特征词出现的个数
方法2:TfidfVectorizer 重要的程度
关键词:在某一类别的文章中,出现的次数多,其他类别的文章中出现的少
分类机器学习算法进行文章分类中前期数据处理方式
def dict_demo():
"""
字典特征提取
:return:
"""
data = [{'city': '北京', 'temperature': 100}, {'city': '上海', 'temperature': 60}, {'city': '深圳', 'temperature': 30}]
#1.实例化一个转换器类
transfer = DictVectorizer(sparse=False)
#2.调用fit_transform()
data_new=transfer.fit_transform(data)
print("data_new:\n",data_new)
print("特征名:\n",transfer.get_feature_names())
return None
def count_demo():
"""
文本特征提取:CountVectorRizer
:return:
"""
data=["life is short,i like like python","life is too long,i diskike python"]
#1.实例化一个转换器类
transfer=CountVectorizer(stop_words=["is","too"])
#2.调用fit_transform()
data_new = transfer.fit_transform(data)
print("特征名:\n", transfer.get_feature_names())
print("data_new:\n",data_new.toarray())
def cut_word(text):
"""
进行中文分词
:param text:
:return:
"""
return " ".join(list(jieba.cut(text)))
def count_chinese_demo():
"""
中文文本特征提起,自动分词
:return:
"""
#1.将中文文本进行分词
data=["大连理工大学(大工,Dalian University of Technology),创建于1949年,坐落于大连市,是教育部直属全国重点大学,教育部与国防科技工业局共建高校,教育部、辽宁省、大连市共建高校,是“世界一流大学”“985工程”“211工程”“双一流”重点建设高校",
"该校入选“2011计划”“111计划”“卓越工程师教育培养计划”“国家建设高水平大学公派研究生项目”“新工科研究与实践项目”、中国政府奖学金来华留学生接收院校、国家实施工程教育改革试点高校、“国家大学生创新性实验计划”“国家级大学生创新创业训练计划”、全国深化创新创业教育改革示范高校、全国高校实践育人创新创业基地、高校科技成果转化和技术转移基地",
"该校是卓越大学联盟、中俄工科大学联盟、中俄交通大学联盟、中欧工程教育平台、中国人工智能教育联席会成员"]
data_list=[]
for item in data:
data_list.append(cut_word(item))
# 1.实例化一个转换器类
transfer = CountVectorizer(stop_words=["is", "too"])
# 2.调用fit_transform()
data_new = transfer.fit_transform(data_list)
print("特征名:\n", transfer.get_feature_names())
print("data_new:\n", data_new.toarray())
def tfidf_demo():
"""
中文文本特征提起,自动分词
:return:
"""
#1.将中文文本进行分词
data=["大连理工大学(大工,Dalian University of Technology),创建于1949年,坐落于大连市,是教育部直属全国重点大学,教育部与国防科技工业局共建高校,教育部、辽宁省、大连市共建高校,是“世界一流大学”“985工程”“211工程”“双一流”重点建设高校",
"该校入选“2011计划”“111计划”“卓越工程师教育培养计划”“国家建设高水平大学公派研究生项目”“新工科研究与实践项目”、中国政府奖学金来华留学生接收院校、国家实施工程教育改革试点高校、“国家大学生创新性实验计划”“国家级大学生创新创业训练计划”、全国深化创新创业教育改革示范高校、全国高校实践育人创新创业基地、高校科技成果转化和技术转移基地",
"该校是卓越大学联盟、中俄工科大学联盟、中俄交通大学联盟、中欧工程教育平台、中国人工智能教育联席会成员"]
data_list=[]
for item in data:
data_list.append(cut_word(item))
# 1.实例化一个转换器类
transfer = TfidfVectorizer(stop_words=["is", "too"])
# 2.调用fit_transform()
data_new = transfer.fit_transform(data_list)
print("特征名:\n", transfer.get_feature_names())
print("data_new:\n", data_new.toarray())
2.特征预处理
为什么要进行归一化/标准化:特征的单位或者大小相差较大,或者某特征的方差相比其他特征要大出几个数量级,容易影响(支配)目标结果,使得一些算法无法学习到其他的特征
无量纲化的处理:使不同规格的数据转换到同一规格
归一化:对原始数据进行变换把数据映射到(默认为[0,1])之间,就是套用公式计算---缺点:容易受到异常值的影响(最大值,最小值),所以鲁棒性较差,只适合传统精确小数据场景
标准化:通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内 (x-mean)/std 均值:平均值 标准值:集中程度 ----在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景
def minmax_demo():
"""
归一化
:return:
"""
# 1.获取数据
data = pd.read_csv("dating.txt")
data = data.iloc[:, :3]
print("data:\n", data)
# 2.实例化一个转换器
transfer = MinMaxScaler(feature_range=[0, 1]) # 默认0~1
# 3.调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
def stand_demo():
"""
标准化
:return:
"""
# 1.获取数据
data = pd.read_csv("dating.txt")
data = data.iloc[:, :3]
print("data:\n", data)
# 2.实例化一个转换器
transfer = StandardScaler()
# 3.调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
3.特征降维
降低维度:此处的降维,降低(随机变量)特征的个数,得到一组”不相关”主变量的过程
两种方式:
- 特征选择
数据中包含冗余或相关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征
Filter过滤式—主要探究特征本身特点、特征与特征的目标值之间关联
方差选择法:低方差特征过滤 VarianceThreshold
相关系数:特征与特征之间的相关程度
取值范围 -1<=r<= 1
皮尔逊相关系数
特征与特征之间相关性很高:1)选取其中一个;2)加权求和;3)主成分分析
- Embeded 嵌入法—算法自动选择特征
决策树
正则化
深度学习
def variance_demo():
"""
过滤低方差特征
:return:
"""
#1.获取数据
data=pd.read_csv("xx.csv")
data=data.iloc[:,1:-2]
print("data:\n",data)
#2.实例化一个转换器
transfer = VarianceThreshold(threshold=10)
#3.调用fit_transform
data_new=transfer.fit_transform(data)
print("data_new:\n",data_new,data_new.sharp)
#计算某两个变量之间的相关系数
r1=pearsonr(data["pe_ratio"],data["pb_ratio"])
print("相关系数:\n",r1)
主成分分析(PCA)
定义:高维数据转化为低维数据的过程,可能会舍弃原有数据、创造新的变量
作用:是数据维数压缩,尽可能降低原有数据的维数,损失少量信息
def pca_demoo():
"""
PCA降维
:return:
"""
data = [[2,8,4,5],[6,3,0,8],[5,4,9,1]]
transfer = PCA(n_components=2)
data_new=transfer.fit_transform(data)
print("data_new:\n",data_new)
return None
分类算法
1.sklearn转换器和预估器
转换器:特征工程的父类
1实例化(实例化都是一个转化器类)
2调用fit_transform(对于文档建立分类词频矩阵,不能同时调用)
估计器(sklearn机器学习算法的实现)estimator
1.实例化一个estimator
2.estimator.fit(x_train,y_train) 计算 ----调用完毕,模型生成
3.模型评估:
1)直接对比真实值和预测值
y_predict = estimator.predict(x_test)
y_test==y_predict
2)计算准确率
accuracy = estimator.score(x_test,y_test)
2.KNN算法
根据你的“邻居”来推断你的类别
原理:
计算距离:距离公式(欧式距离(两点之间的距离),曼哈顿距离(绝对值距离))
k值取得过小,容易受到异常点的影响
k值取得过大,样本不均衡的影响
总结:适用于小数据场景,几千~几万样本
优点
- 简单,易于理解,易于实现,无需训练
缺点
- 懒惰算法,对测试样本分类时的计算量大,内存开销大
- 必须指定K值,K值选择不当则分类精确度不能保证
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
def knn_iris():
# 1)获取数据
iris = load_iris()
# 2)划分数据集
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=22)
# 3)特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)KNN算法预估器
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train,y_train)
# 5)模型评估
# 方法1:直接对比真实值和预测值
y_predict=estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对真实值和预测值:\n",y_test ==y_predict)
# 方法2:计算准确率
score = estimator.score(x_test,y_test)
print("准确率为:\n",score)
return None
3.模型选择与调优
交叉验证(cross validation),为了让被评估的模型更加准确可信
超参数搜索-网格搜索(Grid Search)
k的取值[1,3,5,7,9,11] 暴力破解
#用knn算法对鸢尾花进行分类,添加网格搜索和交叉验证
def knn_iris_gscv():
# 1)获取数据
iris = load_iris()
# 2)划分数据集
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,random_state=22)
# 3)特征工程:标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)KNN算法预估器
estimator = KNeighborsClassifier()
#加上网格搜索和交叉验证
para_dict={"n_neighbors":[1,3,5,7,9,11]}
estimator = GridSearchCV(estimator,param_grid=para_dict,cv=10)
estimator.fit(x_train,y_train)
# 5)模型评估
# 方法1:直接对比真实值和预测值
y_predict=estimator.predict(x_test)
print("y_predict:\n",y_predict)
print("直接比对真实值和预测值:\n",y_test ==y_predict)
# 方法2:计算准确率
score = estimator.score(x_test,y_test)
print("准确率为:\n",score)
print("最佳参数:\n",estimator.best_params_)
print("最佳结果:\n",estimator.best_score_)
print("最佳估计器:\n",estimator.best_estimator_)
print("交叉验证结果:\n",estimator.cv_results_)
return None
4.朴素贝叶斯算法
分类算法,选择概率比较大的作为结果
朴素(假定特征与特征之间是相互独立的)+贝叶斯
遇到概率为0,引入拉普拉斯平滑系数(上下都加 )
优点:对缺失数据不敏感,计算比较快
缺点:假定了特征与特征之间是相互独立
应用场景:文本分类(单词作为特征)
def nb_news():
"""
用朴素贝叶斯算法对新闻进行分类
:return:
"""
# 1)获取数据
news = fetch_20newsgroups(subset="all")
# 2)划分数据集
x_train,x_test,y_train,y_test =train_test_split(news.data,news.target,)
# 3)特征工程:文本特征抽取-tfidf
transfer=TfidfVectorizer()
x_train = transfer.fit_transform(x_train)
x_test=transfer.transform(x_test)
# 4)朴素贝叶斯算法预估器流程
estimator = MultinomialNB()
estimator.fit(x_train,y_train)
# 5)模型评估
# 方法1:直接对比真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
return None
5.决策树
找到最高效的决策顺序–信息增益(提高决策效率)
信息增益 = 信息熵-条件熵
def decision_iris():
"""
用决策树对鸢尾花进行分类
:return:
"""
# 1.获取数据集
iris = load_iris()
# 2.划分数据集
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 3.决策树预估器
estimator = DecisionTreeClassifier(criterion="entropy")
estimator.fit(x_train,y_train)
# 4.模型评估
# 方法1:直接对比真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
#可视化决策树
export_graphviz(estimator,out_file="iris_tree.dot",feature_names=iris.feature_names)
return None
决策树的划分依据之一—信息增益
没有免费的午餐
决策树的可视化
优点:可视化–解释能力强
缺点:容易过拟合
6.随机森林
随机:1训练集随机 2特征随机
森林:多个决策树
在当前所有算法中,具有极好的准确率
能够有效地运行在大数据集上,处理具有高维度特征的输入样本,而且不需要降维
能够评估各个特征在分类问题上的重要性
回归与聚类
线性回归
分类算法:逻辑回归
模型保存与加载
聚类学习 K -means算法
线性回归
函数关系 特征值x,与目标值y
线性关系:类型y=kx+b
线性关系一定是线性模型,线性模型还包含非线性关系,不一定是线性关系
线性回归的损失和优化原理
目标:求模型参数,模型参数使得能够预测准确
损失函数/cost/成本函数/目标函数:
最小二乘法
优化损失
优化方法?
正规方程(天才-直接求解w)
梯度下降(努力的普通人-试错,改进)
无监督学习
无监督学习:从无标签的数据开始学习的
- 聚类
- K-means
- 降维
- PCA
K-means聚类`步骤`
1.随机设置K个特征空间内的点作为初始的聚类中心
2.对于其他每个点计算到K个中心的距离,未知的点选择最近的一个聚类中心点作为标记类别
3.接着对着标记的聚类中心之后,重新计算出每个聚类的新中心点(平均值)
4.如果计算得出的新中心点与原中心点一样,那么结束,否则重新进行第二步过程
Kmeans性能评估指标
轮廓系数的值介于[-1,1],越趋近于1代表内聚度和分离度都相对较优
总结:特点分析:采用迭代式算法,直观易懂并且实用
缺点:容易收敛到局部最优解(多次聚类)
应用:没有目标值,再进行分类
Jupyter Notebook
简单线性回归
0.引入依赖
import numpy as np
import matplotlib.pyplot as plt
1.导入数据(data.csv)
points=np.genfromtxt("data.csv",delimiter=',')
points[0,0]
#两列数据分别作为x,y
x = points[:,0]
y = points[:,1]
# 用plt画出散点图
plt.scatter(x,y)
plt.show()
2.定义损失函数
#损失函数是系数的函数,另外还要传入数据x,y
def compute_cost(w,b,points):
total_cost=0
M=len(points)
#逐点计算平方损失误差,然后求平均数
for i in range(M):
x=points[i,0]
y=points[i,1]
total_cost+=(y-w*x-b)**2
return total_cost/M
3.定义核心算法拟合函数
#先定义求均值的函数
def average(data):
sum=0
num=len(data)
for i in range(num):
sum+=data[i]
return sum/num
#定义核心拟合函数
def fit(points):
M=len(points)
x_bar=average(points[:,0])
sum_yx=0
sum_x2=0
sum_delta=0
for i in range(M):
x=points[i,0]
y=points[i,1]
sum_yx+=y*(x-x_bar)
sum_x2+=x**2
#根据公式计算w
w=sum_yx/(sum_x2-M*(x_bar**2))
for i in range(M):
x=points[i,0]
y=points[i,1]
sum_delta += (y-w*x)
b=sum_delta/M
return w,b
4.测试
w,b=fit(points)
print("w is:",w)
print("b is:",b)
cost=compute_cost(w,b,points)
print("cost is:",cost)
5.画出拟合曲线
plt.scatter(x,y)
#针对每一个x,计算出预测的y值
pred_y=w*x+b
plt.plot(x,pred_y,c='g')
plt.show()
简单线性回归-梯度下降法
import numpy as np
import matplotlib.pyplot as plt
points=np.genfromtxt("data.csv",delimiter=',')
#两列数据分别作为x,y
x = points[:,0]
y = points[:,1]
# 用plt画出散点图
plt.scatter(x,y)
plt.show()
#损失函数是系数的函数,另外还要传入数据x,y
def compute_cost(w,b,points):
total_cost=0
M=len(points)
#逐点计算平方损失误差,然后求平均数
for i in range(M):
x=points[i,0]
y=points[i,1]
total_cost+=(y-w*x-b)**2
return total_cost/M
定义模型的超参数
alpha=0.0001
initial_w = 0
initial_b = 0
num_iter=10
定义核心梯度下降算法函数
def grad_desc(points,initial_w,initial_b,alpha,num_iter):
w=initial_w
b=initial_b
#定义一个list保存所有损失函数值,用来显示下降的过程
cost_list=[]
for i in range(num_iter):
cost_list.append(compute_cost(w,b,points))
w,b=step_grad_desc(w,b,alpha,points)
return [w,b,cost_list]
def step_grad_desc(current_w,current_b,alpha,points):
sum_grad_w=0
sum_grad_b=0
M=len(points)
#对每个点代入公式求和
for i in range(M):
x=points[i,0]
y=points[i,1]
sum_grad_w += (current_w*x+current_b-y)*x
sum_grad_b += current_w*x+current_b-y
#用公式求当前的梯度
grad_w=2/M*sum_grad_w
grad_b=2/M*sum_grad_b
#梯度下降,更新当前的w和b
updated_w=current_w-alpha*grad_w
updated_b=current_b-alpha*grad_b
return updated_w,updated_b
测试,运行梯度下降算法得到最优w和b
w,b,cost_list=grad_desc(points,initial_w,initial_b,alpha,num_iter)
print("w is :",w)
print("b is :",b)
cost = compute_cost(w,b,points)
print("cost is :",cost)
plt.plot(cost_list)
plt.show()
画出拟合曲线
plt.scatter(x,y)
#针对每一个x,计算出预测的y值
pred_y=w*x+b
plt.plot(x,pred_y,c='g')
plt.show()
sklearn库代码实现
import numpy as np
import matplotlib.pyplot as plt
points=np.genfromtxt("data.csv",delimiter=',')
points[0,0]
#两列数据分别作为x,y
x = points[:,0]
y = points[:,1]
# 用plt画出散点图
plt.scatter(x,y)
plt.show()
#损失函数是系数的函数,另外还要传入数据x,y
def compute_cost(w,b,points):
total_cost=0
M=len(points)
#逐点计算平方损失误差,然后求平均数
for i in range(M):
x=points[i,0]
y=points[i,1]
total_cost+=(y-w*x-b)**2
return total_cost/M
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
x_new=x.reshape(-1,1)
y_new=y.reshape(-1,1)
lr.fit(x_new,y_new)
#从训练好的模型中提取系数和截距
w=lr.coef_
b=lr.intercept_
print("w is:",w)
print("b is:",b)
cost=compute_cost(w,b,points)
print("cost is:",cost)
w=lr.coef_[0][0]
b=lr.intercept_[0]
plt.scatter(x,y)
#针对每一个x,计算出预测的y值
pred_y=w*x+b
plt.plot(x,pred_y,c='g')
plt.show()
K means
0.引入依赖
import numpy as np
import matplotlib.pyplot as plt
# 从sklearn中直接生成聚类数据
from sklearn.datasets.samples_generator import make_blobs
1.数据加载
x,y=make_blobs(n_samples=100,centers=6,random_state=1234,cluster_std=0.6)
print(x.shape)
plt.figure(figsize=(6,6))
plt.scatter(x[:,0],x[:,1],c=y)
plt.show()
2.算法实现
#引入scipy中的距离函数,默认欧式距离
from scipy.spatial.distance import cdist
class K_Means(object):
#初始化,参数n_clusters(K)、max_iter(迭代次数)、初始质心centroids
def __init__(self,n_clusters=6,max_iter=300,centroids=[]):
self.n_clusters=n_clusters
self.max_iter=max_iter
self.centroids=np.array(centroids,dtype=np.float)
#训练模型方法,k-means聚类过程,传入原始数据
def fit(self,data):
#假如没有指定初始质心,就随机选取data中的点作为初始质心
if(self.centroids.shape==(0,)):
#从data中随机生成0到data行数的6个整数,作为索引值
self.centroids=data[np.random.randint(0,data.shape[0],self.n_clusters),:]
#开始迭代
for i in range(self.max_iter):
#1.计算距离矩阵,得到的是一个100*6的矩阵
distances=cdist(data,self.centroids)
#2.对距离按由近到远排序,选取最近的质心点的类别,作为当前点的分类
c_ind=np.argmin(distances,axis=1)
#对每一类数据进行均值计算,更新质心点坐标
for i in range(self.n_clusters):
#排除掉没有出现在c_ind里的类别
if i in c_ind:
#选出所有类别是i的点,取data里面坐标的均值,更新第i个质心
self.centroids[i]=np.mean(data[c_ind==i],axis=0)
#实现预测方法
def predict(self,samples):
distances=cdist(samples,self.centroids)
c_ind=np.argmin(distances,axis=1)
return c_ind
3.测试
#定义一个绘制子图的函数
def plotKMeans(x,y,centroids,subplot,title):
#分配子图,121表示1行两列的子图中的第一个
plt.subplot(subplot)
plt.scatter(x[:,0],x[:,1],c='r')
#画出质心点
plt.scatter(centroids[:,0],centroids[:,1],c=np.array(range(6)),s=100)
plt.title(title)
kmeans=K_Means(max_iter=300,centroids=np.array([[2,1],[2,2],[2,3],[2,4],[2,5],[2,6]]))
plt.figure(figsize=(16,6))
plotKMeans(x,y,kmeans.centroids,121,'Initial State')
#开始聚类
kmeans.fit(x)
plotKMeans(x,y,kmeans.centroids,122,'Final State')
#预测新数据点的类别
x_new=np.array([[0,0],[10,7]])
y_pred=kmeans.predict(x_new)
print(kmeans.centroids)
print(y_pred)
plt.scatter(x_new[:,0],x_new[:,1],s=100,c='Yellow')
K近邻算法
0.引入依赖
import numpy as np
import pandas as pd
#sklearn中有数据集,iris鸢尾花数据集
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split #可以切分数据集为训练和测试集
from sklearn.metrics import accuracy_score #计算分类预测的准确率
1.数据加载和预处理
iris = load_iris()
df=pd.DataFrame(data=iris.data,columns=iris.feature_names)
df['class']=iris.target
df['class']=df['class'].map({0:iris.target_names[0],1:iris.target_names[1],2:iris.target_names[2]})
#df
df.describe()
x=iris.data
y=iris.target.reshape(-1,1)#把原本排出任意行一列的列向量
print(x.shape,y.shape)
#划分训练集和测试集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=233,stratify=y)
print(x_train.shape,y_train.shape)
print(x_test.shape,y_test.shape)
2.核心算法实现
#距离函数定义
def l1_distance(a,b):
return np.sum(np.abs(a-b),axis=1)# a是矩阵,b是行向量
def l2_distance(a,b):
return np.sqrt(np.sum((a-b)**2 ,axis=1))
#分类器实现
class kNN(object):
#定义一个初始化方法,__init__是类的构造方法
def __init__(self,n_neighbors=1,dist_func=l1_distance):
self.n_neighbors = n_neighbors
self.dist_func=dist_func
#训练模型方法
def fit(self,x,y):
self.x_train=x
self.y_train=y
#模型预测方法
def predict(self,x):
#初始化预测分类数组
y_pred=np.zeros((x.shape[0],1),dtype=self.y_train.dtype)
#遍历输入的x数据点,取出每一个数据点的序号i和数据x_test
for i,x_test in enumerate(x):
#x_test跟所有训练数据计算距离
distances=self.dist_func(self.x_train,x_test)
#得到的距离按照由近到远排序,取出索引值
nn_index=np.argsort(distances)
#选取最近的k个点,保存下来
nn_y=self.y_train[nn_index[:self.n_neighbors]].ravel()
#统计类别中出现频率最高的那个,赋给y_pred[i]
y_pred[i]=np.argmax(np.bincount(nn_y))
return y_pred
3.测试
#定义一个knn实例
knn=kNN(n_neighbors=3)
#训练模型
knn.fit(x_train,y_train)
#传入测试数据,做预测
y_pred=knn.predict(x_test)
#求出预测准确率
accuracy=accuracy_score(y_test,y_pred)
print("预测准确率:",accuracy)
#定义一个knn实例
knn=kNN(n_neighbors=3)
#训练模型
knn.fit(x_train,y_train)
#保存结果list
result_list=[]
#针对不同参数选取,做预测
for p in [1,2]:
knn.dist_func=l1_distance if p==1 else l2_distance
#考虑不同的k取值,步长为2
for k in range(1,10,2):
knn.n_neighbors=k
#传入测试数据,做预测
y_pred=knn.predict(x_test)
#求出预测准确率
accuracy=accuracy_score(y_test,y_pred)
result_list.append([k,'l1_distance' if p==1 else 'l2_distance',accuracy])
df= pd.DataFrame(result_list,columns=['k','距离函数','预测准确率'])
df