《封号码罗》数据分析与人工智能之KNN分类问题(七)

第一部分

# KNN
# K最近邻(k-Nearest Neighbor,KNN)分类算法:
# 是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。
# 该方法的思路是:
# 在特征空间中,如果一个样本附近的k个最近(即特征空间中最邻近)样本的大多数属于某一个类别,则该样本也属于这个类别。

#  欧几里得距离
# 计算公式(n维空间下)
# 二维:dis=sqrt(  (x1-x2)^2 + (y1-y2)^2  )
# 三维:dis=sqrt( (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2 )

import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier  # 分类问题
from sklearn.neighbors import KNeighborsRegressor  # 回归问题
import time

# 全局配置pandas
pd.set_option('display.max_columns', None)  # None显示所有列
pd.set_option('display.max_rows', 200)  # None显示所有行
pd.set_option('display.width', None)  # 无限宽度
pd.set_option('display.max_colwidth', 200)  # 设置value的显示长度为100,默认为50
pd.set_option("display.float_format", lambda x: "%0.2f" % (x))  # 保留两位小数

# 用pandas展示数据输出时列名不能对齐,是列名用了中文的缘故
# 用下面两个参数 它们的默认设置都是False
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)

movie = pd.read_excel("./movies.xlsx", sheet_name=0)
X = movie[["武打镜头", "接吻镜头"]]  # 取出用于分类的数据,数据决定了类型
y = movie["分类情况"]  # y就是目标值,本数据中的最后一列(分类情况)
# 从数据里面找附近的五个数据,五个数据进行投票划分
# witghts 权重分配,默认是uniform统一权重
# n_jobs 默认为1,单线程计算数据模型,-1为多线程,自动按CPU配置使用多线程
knn = KNeighborsClassifier(n_neighbors=5, weights="distance", n_jobs=-1)
knn.fit(X, y)  # 该方法,就是训练数据

# print(knn.fit(X, y))
# KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
#                      metric_params=None, n_jobs=None, n_neighbors=5, p=2,
#                      weights='uniform')

# 预测新电影
# 电影名称  武打镜头  接吻镜头
# 西游记       100       5
# 水浒传       200       8
# 红楼梦       10       90
# X_test = pd.DataFrame({"武打镜头": [100], "接吻镜头": [5]}) # 测试单个数据
X_test = pd.DataFrame({"武打镜头": [100, 200, 10], "接吻镜头": [5, 8, 90]})
# res = knn.predict(X_test)  # ['动作片' '动作片' '爱情片']
res = knn.predict_proba(X_test)  # 显示概率
# [[0.6 0.4]
#  [0.6 0.4]
#  [0.4 0.6]]

# 计算过程:根据欧几里得公式 在第9行  按照西游记给的数据来分解步骤
s = ((movie["武打镜头"] - 100) ** 2 + (movie["接吻镜头"] - 2) ** 2) ** 0.5
# 0    64.01
# 1    57.00
# 2   100.32
# 3    41.01
# 4    99.85
# 5    99.46
# 给s进行排序
index = s.sort_values().index  # 获取排序之后的index  Int64Index([3, 1, 0, 5, 4, 2], dtype='int64')
classifier = movie["分类情况"][index[:5]]
# print(classifier)
# 3    动作片
# 1    动作片
# 0    动作片
# 5    爱情片
# 4    爱情片
# 投票划分:动作片3票,爱情片2票, 3>2,结果为动作片


start = time.perf_counter()
print(res)
end = time.perf_counter()
print(f"程序运行耗时为{(start - end).__round__(20)}")

第二部分

import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier  # 分类问题
from sklearn.neighbors import KNeighborsRegressor  # 回归问题
import time

# 用pandas展示数据输出时列名不能对齐,是列名用了中文的缘故
# 用下面两个参数 它们的默认设置都是False
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)

# 第一步:导入数据
salary = pd.read_excel("./movies.xlsx")
# 第二步:找准目标值数据
y = salary["分类情况"]
# 第三步:找准测试数据
X = salary.iloc[:, [0, 1, 2]]
# print(X)

# print(X.info())
# 注意:str类型的数据,是不能计算距离的

# 数据预处理。数据转换
workclass = X["电影名称"].unique()
m = {}
for i, work in enumerate(workclass):
    m[work] = i
# print(m)
X["电影名称"] = X["电影名称"].map(m)  # map在内的字典映射

# 假如还有列是字符串类型的数据
for col in X.columns[1:]:  # 遍历所有的字符串类型的列
    u = X[col].unique()  # 首先找到当前列的去重值   u是去重之后的列表


    def convert(x):
        # u是去重之后的列表 x是当前列中每一行的值,因为map会遍历每一行的值
        # np.argwhere( a ) 返回非0的数组元组的索引,其中a是要索引数组的条件。
        # 返回的是数组,那条件就是u列表里面的某个数据等于穿过来的x,返回u的索引位置
        # 返回值如[[5]],使用[0,0]就可以取出这个索引
        return np.argwhere(u == x)[0, 0]


    # u = X["电影名称"].unique()    ["西游记","红楼梦","水浒传"]
    # u == "红楼梦"  [False,True,False]    返回True的索引
    # np.argwhere(u == "红楼梦")[0, 0]
    # 拿到convert返回来的索引值,在复制给当前列该行的值
    X[col] = X[col].map(convert)  # map(可以是字典也可以是方法)

from sklearn.model_selection import train_test_split  # 分割训练集和测试集

a = np.arange(100)
b = a * 10
# a_train, a_test = train_test_split(a, test_size=0.2)
# a_train, a_test, b_train, b_test = train_test_split(a, b, test_size=0.2)  # 拆分的时候一一对应
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)  # 拆分的时候一一对应
# print(a_train, "\n", a_test)
# print(a_train, "\n", a_test, b_train, "\n", b_test)

# print(X.head())
# print(X.columns)

# 第四步:声明knn算法对象
knn = KNeighborsClassifier(n_neighbors=4)
# 第五步:测试模型
knn.fit(X_train, y_train)
# 第六步:评估
y_ = knn.predict(X_test)
res = y_ == y_test
res.mean()
# 第七步:优化-,消除属性的差异
# 查看数据是否可以归一化  最大值,最小值
v_min = X.min()
v_max = X.max()
X2 = (X - v_min) / (v_max - v_min)
X2_train, X2_test, y2_train, y2_test = train_test_split(X2, y, test_size=0.2)  # 拆分的时候一一对应
knn2 = KNeighborsClassifier(n_neighbors=4, weights="distance")
knn2.fit(X2_train, y2_train)
y2_ = knn2.predict(X2_test)
res2 = y2_ == y2_test
res2.mean()

# 第七步:优化二,Z-score
v_mean = X.mean()
v_std = X.std()
X3 = (X - v_mean) / v_std
X3_train, X3_test, y3_train, y3_test = train_test_split(X3, y, test_size=0.2)  # 拆分的时候一一对应
knn3 = KNeighborsClassifier(n_neighbors=4, weights="distance")
knn3.fit(X3_train, y3_train)
y3_ = knn3.predict(X3_test)
res3 = y3_ == y3_test
res3.mean()

# 第七步:优化三 使用封装好的包,和上面的归一化一样StandardScaler,MinMaxScaler
from sklearn.preprocessing import StandardScaler, MinMaxScaler

s = StandardScaler()  # 和Z-score操作相等
X4 = s.fit_transform(X)  # 返回一个ndarray对象,没有head()方法,DataFrame才有
# print(X4)

s2 = MinMaxScaler()  # 和最大值,最小值归一化操作相等
X5 = s2.fit_transform(X)  # 返回一个ndarray对象,没有head()方法,DataFrame才有
# print(X5)

# map()方法转成数值型数据  这个过程就是量化  数量化的简称就是量化
# 金融量化,就是把里面一些字符数据转换成合理的数值型数据

# 数据提升:
# 修改算法参数
# 处理数据
# 数据挖掘,添加一列(自由组合某一列和另一列聚合之类的操作等等)

# 保存模型  externals 美[ɪkˈstɜːrnlz]  外表; 外观; 外貌;
from sklearn.externals import joblib  # 方法被弃用,直接使用下面这个包
import joblib

# joblib.dump(knn, "./model")
# joblib.dump(knn, "./model", compress=9)  # 0~9 数字越大,压缩的越小
model = joblib.load("./model")  # 导入模型
score = model.score(X_test, y_test)  # 使用测试集评估准确率

start = time.perf_counter()
# print(X_train, "\n", X_test, "\n", y_train, "\n", y_test)
print(score)
end = time.perf_counter()
print(f"程序运行耗时为{(start - end).__round__(20)}")

第三部分

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值