1 day ago

1.tensorflow求解已知函数梯度

# 求解函数(3*X1+4*X2)**2在点(2,3)处的梯度
# tf.tf.gradients()
import tensorflow as tf
import numpy as np

# 将变量x申请为一个占位符
x = tf.placeholder(tf.float32,(2,1))
w = tf.constant([[3,4]],tf.float32) # 需要两个[]才能表示w的形状为(1,2)
y = tf.matmul(w,x) # matmul是math-multiply的简写
f = tf.pow(y,2)
grad = tf.gradients(f,x)
with tf.Session() as sess:
    sess.run(grad,{x:np.array([[2],[3]])} # 这里的np.array是重点

2.梯度下降算法核心代码

# 对一元函数(x-1)**2实现梯度下降算法
# tf.train.GradientDescentOptimizer()
import tensorflow as tf

# 初始化变量:梯度下降的起始点
x=tf.Variable(4.0,tf.float32)
# 其实,一行代码就可以实现随机梯度下降,是不是很机智😊😊
# x=tf.Variable(tf.random_uniform((1,),minval=-8,maxval=10,dtype=tf.float32))
# 函数
y=tf.pow(x-1,2.0)
# 梯度下降:学习率设置为0.05
opti=tf.train.GradientDescentOptimizer(0.05).minimize(y)
# 创建会话
with tf.Session() as sess:
    # Variable对象初始化
  sess.run(tf.global_variables_initializer())
  print("x的初始值为:",sess.run(x))
  # 三次迭代
  for i in range(3):
    sess.run(opti)
    print("第%d次迭代后的x值为%f" %(i+1,sess.run(x)))

运行结果如下:

x的初始值为: 4.0
第1次迭代后的x值为2.500000
第2次迭代后的x值为1.750000
第3次迭代后的x值为1.375000

3.梯度下降过程的图形化展示

1)首先画出函数(x-1)**2的图像

import matplotlib.pyplot as plt

# 准备x坐标数据
a=np.linspace(-8.0,10.0,100)
# 准备对应的y数据
b=[np.power(i-1,2) for i in a]
# 画图
plt.plot(a,b)
plt.show()


2)梯度下降过程核心代码演示

import matplotlib.pyplot as plt

# 准备x坐标数据
a=[4,2.5,1.75,1.375]
# 准备对应的y数据
b=[np.power(i-1,2) for i in a]
# 画图
plt.plot(a,b)
plt.show()

4.代码合并(一元函数的梯度下降)

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt


# 1)函数图形化展示,数据准备
a=np.linspace(-2,4,100)
b=[np.power(i-1,2) for i in a]

# 2)实现梯度下降
x=tf.Variable(4.0,tf.float32)
y=tf.pow(x-1,2.0)
opti=tf.train.GradientDescentOptimizer(0.25).minimize(y)
with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  aa=[]
  xtemp=sess.run(x)
  print("x的初始值为:",xtemp)
  aa.append(xtemp)
  for i in range(3):
    sess.run(opti)
    xtemp=sess.run(x)
    print("第%d次迭代后的x值为%f" %(i+1,xtemp))
    aa.append(xtemp)
    
# 3)梯度下降过程的图形化展示,数据准备
bb=[np.power(i-1,2) for i in aa]

# 4)画图
plt.figure(figsize=(10,8))
plt.plot(a,b)
plt.plot(aa,bb)
plt.grid()
plt.xticks(np.linspace(-2,4,7))
for i in range(len(aa)):
    plt.plot([aa[i],aa[i]],[0,bb[i]],linestyle="--")
# 相当于np.arange(-2,4,1)
plt.show()

5.两元函数的梯度下降

# 以 X1**2+X2**2 为例,初始值为(-4,4)
import tensorflow as tf

# 初始化变量
x1=tf.Variable(-4.0,tf.float32)
x2=tf.Variable(4.0,tf.float32)
# 构造函数
y=tf.square(x1)+tf.square(x2)
# 调用梯度下降算法
grad=tf.train.GradientDescentOptimizer(0.25).minimize(y)
# 创建会话
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print("x1,x2的初始值分别为:%f,%f" %(sess.run(x1),sess.run(x2)))
    for i in range(3):
        sess.run(grad)
        v1=sess.run(x1)
        v2=sess.run(x2)
        print("第%d次迭代后,x1与x2的值分别为:%f,%f" %(i+1,v1,v2))

计算结果如下:

x1,x2的初始值分别为:-4.000000,4.000000
第1次迭代后,x1与x2的值分别为:-2.000000,2.000000
第2次迭代后,x1与x2的值分别为:-1.000000,1.000000
第3次迭代后,x1与x2的值分别为:-0.500000,0.500000

6.多元函数的梯度下降

# 以上代码将两个变量分别进行初始化,若自变量比较多,这种写法就不方便了
# 多自变量应该采取矩阵的形式初始化自变量
# 下面仅以两元函数做示范
import tensorflow as tf

x=tf.Variable(tf.constant([-4.0,4.0],tf.float32))
y=tf.square(x)
grad=tf.train.GradientDescentOptimizer(0.25).minimize(y)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print("x的初始值为:",end="")
    print(sess.run(x))
    for i in range(3):
        sess.run(grad)
        print("第%d次迭代后,x的值为:" %(i+1),end="")
        print(sess.run(x))

运算结果为:

x的初始值为:[-4.  4.]
第1次迭代后,x的值为:[-2.  2.]
第2次迭代后,x的值为:[-1.  1.]
第3次迭代后,x的值为:[-0.5  0.5]
 
3 days ago

1.遇到什么问题

我在使用ipic图床时遇到一个小问题,直接上图来说

原始图片是酱紫的


上传后发现图片左侧和下侧的坐标数字被盖住了

2.问题如何解决

我将问题提交到ipic官网,得到工作人员的简单回复


由此了解到两个新知识
1)图片的透明度
通常我们认为图片只有RGB三个维度
此外,图像还包含第四个不可见通道,即包含透明度信息的 Alpha 通道。有时,此类图像称为 RGBA 图像

这个透明度之前在做图片展示的时候是有发现的,该图片数据为4通道(当时很困惑,但是没办法想太多)


原始图片是这样的

查看该图片的属性,确实发现有透明度信息(即alpha通道)

2)ipic图床默认使用微博图床,微博图床只支持jpg格式
不管用户上传什么格式的图片,微博会转换成jpg格式的图片返回给用户
也就是说原始图片是带有透明度信息的,图床在转换的过程中丢失了透明度通道,由此导致坐标数字被掩盖的现象

3.如何解决

从原始图片着手,去除透明度信息
最简单的办法就是不要直接上传原始图片,先截屏后(截屏软件丢掉了原始图片的透明度信息)再上传,问题解决

参考资料:
ipic官方使用教程
新浪微博图床的 Chrome 扩展
关于Alpha通道和遮罩
去除图像中的alpha通道或透明度

 
3 days ago

1.背景知识

1)生活中据大部分数据都满足正态分布,其均值、中位数、众数相等
2)正态分布概率密度公式

2.代码实现

import numpy as np
import matplotlib.pyplot as plt

# 原始数据:先随机生成一个正态分布数组,模拟实际数据(均值为165cm,标准差为10cm的身高数据)
data=np.random.normal(165,10,(1000))

# 实现正态分布概率密度函数
mean=data.mean() # 计算原始数据的均值
std=data.std() # 计算原始数据的标准差
x=list(np.arange(130,200,1))
y=1.0/(np.sqrt(2*np.pi)*std)*np.exp(-np.power((x-mean),2)/2/np.power(std,2))
plt.plot(x,y)
# 显示直方图📊(normed这个参数指定密度,也就是每个条状图的占比,总的比例默认为1)
plt.hist(data,30,normed=True)

plt.show()

结果很完美


参考资料:
均值、众数、中位数不同分布中的值比较
hist的使用

 
3 days ago

1.tensorflow小知识

1)tensorflow中对张量,可以理解为n维数组或者矩阵
2)tensorflow通过创建会话(session),将张量转化为Numpy类型的数组(ndarray)

2.图像读取步骤

1)通过函数tf.read_file读取本地图像文件
2)利用函数tf.image.decode_png解码为张量
不同的文件类型有不同的解码API

3.代码实现

import tensorflow as tf
import matplotlib.pyplot as plt

# 读取图像文件
img = tf.read_file("../data/running_man.png","r")
# 将图像文件解码为tensor
img_tensor=tf.image.decode_png(img)
# 将tensor转换为numpy类型的数组(ndarray)
with tf.Session() as sess:
    img_ndarray = sess.run(img_tensor)
# 查看图片维度
print(img_ndarray.shape)
# 显示图片
plt.imshow(img_ndarray)
plt.show()

大功告成

参考资料:
张平:《图解深度学习与神经网络》

 
5 days ago

1.用Tensorflow实现一个最基本的线性回归

# 假设随机指定100个点,只有一个特征
# 数据本身的分布为 y = 0.7 * x + 0.8

import matplotlib.pyplot as plt
import tensorflow as tf

x_data = tf.random_normal([100, 1], mean=1.0, stddev=1.0, name="x_data")
y_true = tf.matmul(x_data, [[0.7]]) + 0.8
with tf.variable_scope("linea_model"):
    # 建立回归模型,分析别人的数据的特征数量--->权重数量, 偏置b
    # 由于有梯度下降算法优化,所以一开始给随机的参数,权重(按照正态分布赋值)和偏置
    # 被优化的参数,必须得使用变量op去定义
    # 变量初始化权重和偏置
    # weight 2维[1, 1]    bias [1]
    # 变量op当中会有trainable参数决定是否训练
    weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0),
                             name="weights")

    bias = tf.Variable(0.0, name='biases')

    # 建立回归公式去得出预测结果
    y_predict = tf.matmul(x_data, weight) + bias
loss = tf.reduce_mean(tf.square(y_true - y_predict))
train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # 在没训练,模型的参数值
    print("初始化的权重:%f, 偏置:%f" % (weight.eval(), bias.eval()))
    # 开启训练
    # 训练的步数(依据模型大小而定)
    saver = tf.train.Saver()
    #for i in range(FLAGS.max_step):
    temp=[]
    for i in range(100):
        sess.run(train_op)
        # 生成事件文件,观察图结构
        #file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph)
        print("训练第%d步之后的损失:%f, 权重:%f, 偏置:%f" % (
            i,
            loss.eval(),
            weight.eval(),
            bias.eval()))
        
        temp.append(loss.eval())
# 展示梯度下降过程
plt.plot([i+1 for i in range(len(temp))],temp)
plt.grid()
plt.show()

2.超参数调参

显然这里的超参数只有学习率learning-rate
1)学习率为0.1


迭代60次后收敛到10的-6次方以下
2)学习率为0.2

迭代30次后收敛到10的-6次方以下
3)学习率为0.3

迭代20次后收敛到10的-6次方以下
4)学习率为0.4

出现的梯度爆炸情况(学习率过大越过了最低点)
5)学习率0.01

迭代100次后收敛到10的-4次方以下

3.结论

论梯度下降求解中,设置学习率的重要性

 
7 days ago

1.constant(常量构造函数)

cons = tf.constant(value=[1,2],dtype=tf.float32,shape=(1,2),name='testconst', verify_shape=False)

必须指定初始值,使用的时候直接调用
一旦指定,后期无法更改(如果使用原名称重新赋值的话,其实是重定向,就是另一个常量了)
作为计算图的起始节点,起到为整个网络传入初始数据的作用
非常底层,只是用来为占位符placeholder或变量Variable生成数据的

import tensorflow as tf
# 实现一个加法运算
a = tf.constant(3.0)
b = tf.constant(4.0)

sum = tf.add(a, b)

# 会话,默认只能运行默认的图,不能运行其它的(可以通过参数解决)
with tf.Session() as sess:
    print(sess.run[a,b,sum])

2.placeholder(占位符,函数)

tf.placeholder(dtype, shape=None, name=None) 

也是一种常量,创建的时候不需要指定初始值,需要在使用的时候指定
此函数可以理解为形参,用于定义过程,在执行的时候再赋具体的值
可以多次使用,每次设置不同的初始值
通常,placeholder用于传入训练数据

import tensorflow as tf
import numpy.random as random

#占位符shape不设时会按传入参数自行匹配
node1 = tf.placeholder(tf.float32)  # , shape=[4, 5])
node2 = tf.placeholder(tf.float32)  # , shape=[4, 5])
op = tf.multiply(node1, node2)
session = tf.Session()
const1 = tf.constant(random.rand(4, 5))
const2 = tf.constant(random.rand(4, 5))
#可以传入初始化后的常量
print(session.run(op, {node1: session.run(const1), node2: session.run(const2)}))
#也可以直接传入张量,其实同初始化后的常量一致
print(session.run(op, {node1: random.rand(2, 3), node2: random.rand(2, 3)}))

3.Variable(变量,类)

tf.Variable(initial_value=None,trainable=True,collections=None,name=None)

创建时必须指定初始值
后期可以重新指定值,需要使用特定的方法
使用前需要初始化运行
通常,Variable用来设置我们需要得到的训练参数(例如权重w和截距b,所以有个trainable参数)

var = tf.Variable(tf.random_normal([2, 2], mean=0.0, stddev=1.0), name="var", trainable=True)
# 给变量赋一个新的值
var1 = var.assign([[2, 3], [4, 5]])
# 给变量做加法
var2 = var.assign_add([[1, 3], [4, 5]])
# 添加一个初始化变量的OP
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
    # 运行初始化op
    sess.run(init_op)
    # 初始化变量var
    print(sess.run(var))
    # 在var的基础上赋新值给var1
    print(sess.run(var1))
    # var1赋值后发现var也发生了改变
    print(sess.run(var))
    # 在var的基础上做加法,赋值给新的变量var2
    print(sess.run(var2))
    # var2后发现var也发生了改变
    print(sess.run(var))   

参考资料:
TensorFlow学习笔记——节点(constant、placeholder、Variable)
Variable() placeholder() constant() 的区别
What's the difference between tf.placeholder and tf.Variable?

 
10 days ago

1.随机森林API介绍

sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, random_state=None, min_samples_split=2)

随机森林分类器
n_estimators:integer,optional(default = 10)森林里的树木数量120,200,300,500,800,1200
criteria:string,可选(default =“gini”)分割特征的测量方法
max_depth:integer或None,可选(默认=无)树的最大深度 5,8,15,25,30
max_features="auto”,每个决策树的最大特征数量
If "auto", then max_features=sqrt(n_features).
If "sqrt", then max_features=sqrt(n_features) (same as "auto").
If "log2", then max_features=log2(n_features).
If None, then max_features=n_features.
bootstrap:boolean,optional(default = True)是否在构建树时使用放回抽样
min_samples_split:节点划分最少样本数
min_samples_leaf:叶子节点的最小样本数
超参数:n_estimator, max_depth, min_samples_split,min_samples_leaf

2.实现随机森林算法

from sklearn.ensemble import RandomForestClassifier
titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
def random_forest(titan):
    """
    随机森林进行乘客生存预测
    :return:
    """
    # 1、获取数据
    # titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")

    # 2、数据的处理
    x = titan[['pclass', 'age', 'sex']]

    y = titan['survived']

    # print(x , y)
    # 缺失值需要处理,将特征当中有类别的这些特征进行字典特征抽取
    x['age'].fillna(x['age'].mean(), inplace=True)

    # 对于x转换成字典数据x.to_dict(orient="records")
    # [{"pclass": "1st", "age": 29.00, "sex": "female"}, {}]

    dict = DictVectorizer(sparse=False)

    x = dict.fit_transform(x.to_dict(orient="records"))
    
    print(dict.get_feature_names())
    print(x)

    # 分割训练集合测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)

    # 进行决策树的建立和预测
    rf = RandomForestClassifier(n_estimators=10, max_depth=5)

    rf.fit(x_train, y_train)

    # print("预测的准确率为:", rf.score(x_test, y_test))

    return rf.score(x_test, y_test)

3.多次迭代求取平均值

import matplotlib.pyplot as plt
def score_avg(func,num):
    score_sum=0
    a=[]
    b=[]
    for i in range(1,num+1):
        score_sum += func(titan)
        # 每10次查看一下准确率
        #if i%10==0:
        score_ave = score_sum/(i)
        a.append(i)
        b.append(score_ave)
    # 获取最终的准确率
    print(score_ave)
    # 将准确率变化过程展示出来
    plt.plot(a,b)
    plt.grid()
    plt.show()

4.运行结果

num=5000
score_avg(random_forest,num)


从1000次之后,准确率收敛到0.823
随机森林中有各种超参数,可以使用网格搜索进行调优

5.结论

1)在当前所有算法中,具有极好的准确率
2)集成学习方法可以应用于所有的算法,比如之前学的K近邻和朴素贝叶斯(可惜没有现成的API供调用)
3)集成学习方法可以把预测的准确性在原有算法的基础上提高1%-2%,运算复杂度大大提升,所以关键在于原有算法的准确性

 
10 days ago

1.使用经典数据集:泰坦尼克号乘客生存预测

titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")

2.实现决策树算法

from sklearn.tree import DecisionTreeClassifier
def decisioncls(titan):
    """
    决策树进行乘客生存预测
    :return:
    """
    # 1、获取数据
    #titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")

    # 2、数据的处理
    x = titan[['pclass', 'age', 'sex']]

    y = titan['survived']

    # print(x , y)
    # 缺失值需要处理,将特征当中有类别的这些特征进行字典特征抽取
    x['age'].fillna(x['age'].mean(), inplace=True)

    # 对于x转换成字典数据x.to_dict(orient="records")
    # [{"pclass": "1st", "age": 29.00, "sex": "female"}, {}]

    dict = DictVectorizer(sparse=False)

    x = dict.fit_transform(x.to_dict(orient="records"))
    
    print(dict.get_feature_names())
    print(x)

    # 分割训练集合测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)

    # 进行决策树的建立和预测
    dc = DecisionTreeClassifier(max_depth=5)

    dc.fit(x_train, y_train)

    # print("预测的准确率为:", dc.score(x_test, y_test))
    # export_graphviz(dc, out_file="./tree.dot", feature_names=['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])

    return dc.score(x_test, y_test)

3.多次迭代求取平均值

import matplotlib.pyplot as plt
def score_avg(func,num):
    score_sum=0
    a=[]
    b=[]
    for i in range(1,num+1):
        score_sum += func(titan)
        # 每10次查看一下准确率
        #if i%10==0:
        score_ave = score_sum/(i)
        a.append(i)
        b.append(score_ave)
    # 获取最终的准确率
    print(score_ave)
    # 将准确率变化过程展示出来
    plt.plot(a,b)
    plt.grid()
    plt.show()

4.运行结果

from sklearn.tree import DecisionTreeClassifier
from sklearn.feature_extraction import DictVectorizer
num=100
score_avg(decisioncls,num)


从第10次运算,准确率已经收敛到0.820

5.将决策树图形导出

1)sklearn.tree.export_graphviz() 该函数能够导出DOT格式
tree.export_graphviz(estimator, out_file='tree.dot’,feature_names=[ ' ', ' ' ])
在单次运行程序中加入以下代码

export_graphviz(dc, out_file="./tree.dot", feature_names=['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])

2)工具graphviz: 能够将dot文件转换为pdf、png
ubuntu: sudo apt-get install graphviz
Mac: brew install graphviz
3)运行命令

dot -Tpng tree.dot -o tree.png

 
10 days ago

1.导入数据集

from sklearn.datasets import fetch_20newsgroups
news = fetch_20newsgroups(subset='all')

2.实现KNN算法

from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.feature_extraction.text import TfidfVectorizer
def knn(news):
    """
    k近邻对新闻数据集进行预测
    :return:
    """
    # 获取新闻的数据,20个类别
    

    # 进行数据集分割
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.3)

    # 对于文本数据,进行特征抽取
    tf = TfidfVectorizer()

    x_train = tf.fit_transform(x_train)

    # 不能调用fit_transform
    x_test = tf.transform(x_test)

    # estimator估计器流程
    knn = KNeighborsClassifier(n_neighbors=5)

    knn.fit(x_train, y_train)

    return knn.score(x_test, y_test)

3.实现朴素贝叶斯算法

from sklearn.naive_bayes import MultinomialNB
def nbcls(news):
    """
    朴素贝叶斯对新闻数据集进行预测
    :return:
    """
    # 获取新闻的数据,20个类别
    

    # 进行数据集分割
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.3)

    # 对于文本数据,进行特征抽取
    tf = TfidfVectorizer()

    x_train = tf.fit_transform(x_train)

    # 不能调用fit_transform
    x_test = tf.transform(x_test)

    # estimator估计器流程
    mlb = MultinomialNB(alpha=1.0)

    mlb.fit(x_train, y_train)

    return mlb.score(x_test, y_test)

4.多次迭代运算求取平均值

import matplotlib.pyplot as plt
def score_avg(func,num):
    score_sum=0
    a=[]
    b=[]
    for i in range(1,num+1):
        score_sum += func(news)
        # 每10次查看一下准确率
        #if i%10==0:
        score_ave = score_sum/(i)
        a.append(i)
        b.append(score_ave)
    # 获取最终的准确率
    print(score_ave)
    # 将准确率变化过程展示出来
    plt.plot(a,b)
    plt.grid()
    plt.show()

5.运行结果比较

1)运行KNN算法

num=10
score_avg(knn,num)


从第60次开始准确率收敛到0.786附近
2)运行bayas算法

num=100
score_avg(nbcls,num)


从第55次开始准确率收敛到0.845附近

6.结论

文本分类采用bayas算法更加合适

 
10 days ago

1.使用sklearn的鸢尾花数据集

from sklearn.datasets import load_iris
iris = load_iris()

2.调用K近邻分类器API

from sklearn.neighbors import KNeighborsClassifier

3.代码实现KNN

def knn(data):
    """
    K近邻算法预测鸢尾花种类
    :return:
    """
    # 一、处理数据以及特征工程

    # 1、取出特征值和目标值
    y = data['target']
    x = data.drop(['target'], axis=1)

    # 2、数据分割与特征工程?

    # (1)、数据分割
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)

    # (2)、标准化
    std = StandardScaler()

    # 队训练集进行标准化操作
    x_train = std.fit_transform(x_train)

    # 进行测试集的标准化操作
    x_test = std.fit_transform(x_test)

    # 二、算法的输入训练预测
    # K值:算法传入参数不定的值    理论上:k = 根号(样本数)
    # K值:后面会使用参数调优方法,去轮流试出最好的参数[1,3,5,10,20,100,200]
    knn = KNeighborsClassifier(n_neighbors=1)

    # 调用fit()
    knn.fit(x_train, y_train)

    # 预测测试数据集,得出准确率
    y_predict = knn.predict(x_test)

    print("预测测试集类别:", y_predict)

    print("准确率为:", knn.score(x_test, y_test))

    return None

此时直接调用函数 knn(iris) 即可得出预测结果

4.超参数调优----网格搜索(Grid Search)

# 网格搜索调优
from sklearn.model_selection import GridSearchCV
from pprint import pprint
def knn2(data):
    """
    K近邻算法预测鸢尾花种类
    :return:
    """

    # 1、取出特征值和目标值
    y = data['target']

    x = data.drop(['target'], axis=1)

    # 2、数据分割与特征工程?

    # (1)、数据分割
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)

    # (2)、标准化
    std = StandardScaler()

    # 队训练集进行标准化操作
    x_train = std.fit_transform(x_train)
    print(x_train)

    # 进行测试集的标准化操作
    x_test = std.fit_transform(x_test)
    
    # 网格搜索调优
    knn = KNeighborsClassifier()

    param = {"n_neighbors": [i for i in range(1,10)]}

    gc = GridSearchCV(knn, param_grid=param, cv=10)

    gc.fit(x_train, y_train)

    print("选择了某个模型测试集当中预测的准确率为:", gc.score(x_test, y_test))

    # 训练验证集的结果
    print("在交叉验证当中验证的最好结果:", gc.best_score_)
    print("gc选择了的模型K值是:", gc.best_estimator_)
    #print("每次交叉验证的结果为:", gc.cv_results_)
    pprint(gc.cv_results_)
    
    return None

运行函数 knn2(iris) 即可得到预测结果

5.追求准确率的稳定性----多次计算求平均值

以上代码运行中发现一个问题:每次运行后产生的准确率不同,甚至相差悬殊——最小70%,最大90%
产生原因:算法相同,训练集随机产生,带来不同的结果
由此验证机器学习领域经典语录:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已
为了追求准确率的稳定性,这里尝试采用 多次计算求取平均值的做法
首先需要对KNN代码返回值做下修改

def iris_knn(iris):
    x=iris.data
    y=iris.target
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
    x_train=std.fit_transform(x_train)
    x_test=std.fit_transform(x_test)
    knn=KNeighborsClassifier(n_neighbors=3)
    knn.fit(x_train,y_train)
    # 返回准确率
    return knn.score(x_test,y_test)

多次运算求取平均值

from matplotlib.pyplot as plt
def score_avg():
    num=5000
    score_sum=0
    a=[]
    b=[]
    for i in range(1,num+1):
        score_sum += iris_knn(iris)
        # 每10次查看一下准确率
        if i%10==0:
            score_ave = score_sum/(i)
            a.append(i)
            b.append(score_ave)
    # 获取最终的准确率
    print(score_ave)
    # 将准确率变化过程展示出来
    plt.plot(a,b)
    plt.grid()
    plt.show()

运行函数 score_avg()即可得到结果


可以看到迭代2000次之后准确率稳定在0.919附近

以上 超参数调优稳定准确率 方法可以应用与各种任何数据集和算法

参考资料:
探索sklearn | 鸢尾花数据集