机器学习练手(二):基于KMeans的股票分类

embedded/2024/9/23 9:35:05/

总结:本文为和鲸python 可视化探索训练营资料整理而来,加入了自己的理解(by GPT4o)

原活动链接

在前一关我们学习了逻辑回归,学会如何训练模型、数据基础性分析、如何处理空值等操作,下面我们开始新的一关 KMeans

目录

      • KMeans
      • 基于 `KMeans` 的股票分类
        • 引入依赖
        • 加载数据
        • 确定分类个数
        • 查看分类结果
        • 总结
      • 闯关题
        • STEP1:请根据要求完成题目

KMeans

KMeans 是我们最常用的基于欧式距离的聚类算法,其认为两个目标的距离越近,相似度越大。

KMeans 算法的思想很简单,对于给定的样本集,按照样本之间的距离大小,将样本集划分为 K 个簇,其目的是让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。

基于 KMeans 的股票分类

以往的量化投资中对于股票的划分分类,通常取决于行业、市值、地域等等指标划分,而这些分类指标并不能很好的区分公司的好坏。而现在可以通过每日的交易行情实时划分分类,通过计算当日前一个月的分类从而确定该股票分类,更好的降低投资风险,提供风险对冲。该数据集有 2024-05-06 的全部上市公司股票交易行情信息,其中包含日期、开盘价、收盘价、最高价、最低价、成交量、成交额等特征信息,另外该模型使用的数据为真实数据,可以在实际操作中使用。

股市有风险,入市需谨慎!

引入依赖
import pandas as pd
import numpy as np
import matplotlib.pyplot as pltfrom sklearn.cluster import KMeans
from sklearn.metrics import accuracy_score, silhouette_score
加载数据
# 1. 加载数据stock = pd.read_csv('./data/stocks-2.csv', index_col='Unnamed: 0')
stock.head()
symbolcodenametradepricechangechangepercentbuysellsettlementopenhighlowvolumeamountticktimeperpbmktcapnmcturnoverratio
0sz0000011平安银行10.890.100.92710.8810.8910.7910.9611.1110.84178410057195381749315:00:004.8400.5082.113304e+072.113264e+070.91938
1sz0000022万 科A7.460.050.6757.457.467.417.637.887.44524493788399692170315:00:007.2430.3558.900309e+067.248834e+065.39773
2sz0000044国华网安10.440.232.25310.4310.4410.219.9910.469.97988544010205984215:00:00-8.8217.4781.382050e+051.318448e+057.82769
3sz0000066深振业A3.870.000.0003.873.883.873.964.013.86231871869134876515:00:00-6.5090.7525.224481e+055.224451e+051.71759
4sz0000077*ST全新4.09-0.15-3.5384.094.104.244.264.264.0424405501002858915:00:0039.40311.2121.416972e+051.263597e+050.78995
stock.info()
<class 'pandas.core.frame.DataFrame'>
Index: 5360 entries, 0 to 5359
Data columns (total 20 columns):#   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  0   symbol         5360 non-null   object 1   code           5360 non-null   int64  2   name           5360 non-null   object 3   trade          5360 non-null   float644   pricechange    5360 non-null   float645   changepercent  5360 non-null   float646   buy            5360 non-null   float647   sell           5360 non-null   float648   settlement     5360 non-null   float649   open           5360 non-null   float6410  high           5360 non-null   float6411  low            5360 non-null   float6412  volume         5360 non-null   int64  13  amount         5360 non-null   int64  14  ticktime       5360 non-null   object 15  per            5360 non-null   float6416  pb             5360 non-null   float6417  mktcap         5360 non-null   float6418  nmc            5360 non-null   float6419  turnoverratio  5360 non-null   float64
dtypes: float64(14), int64(3), object(3)
memory usage: 879.4+ KB
# 2. 删除与分类数无关的特征列new_stock = stock.drop(['symbol', 'code', 'name', 'ticktime'], axis=1)
new_stock.head()
tradepricechangechangepercentbuysellsettlementopenhighlowvolumeamountperpbmktcapnmcturnoverratio
010.890.100.92710.8810.8910.7910.9611.1110.8417841005719538174934.8400.5082.113304e+072.113264e+070.91938
17.460.050.6757.457.467.417.637.887.4452449378839969217037.2430.3558.900309e+067.248834e+065.39773
210.440.232.25310.4310.4410.219.9910.469.979885440102059842-8.8217.4781.382050e+051.318448e+057.82769
33.870.000.0003.873.883.873.964.013.862318718691348765-6.5090.7525.224481e+055.224451e+051.71759
44.09-0.15-3.5384.094.104.244.264.264.0424405501002858939.40311.2121.416972e+051.263597e+050.78995
确定分类个数
# 3. 利用肘部法则确定分类inertia = []
silhouette_scores = []
i_range = range(2, 11)
for i in i_range:kmeans = KMeans(n_clusters=i, random_state=10).fit(new_stock)inertia.append(kmeans.inertia_)silhouette_scores.append(silhouette_score(new_stock, kmeans.labels_))inertia, silhouette_scores
([4.1450149552461185e+20,2.189263003520667e+20,1.6730094412041477e+20,9.618885942140525e+19,6.943786093529641e+19,5.561627387942571e+19,4.014992267655058e+19,3.2416675726264095e+19,2.4597061039181627e+19],[0.8944521948807374,0.8260147612056037,0.7907694574915884,0.7490320699906337,0.6649888612149094,0.6339363805356698,0.6338265053972817,0.6300107391392652,0.6195255140687659])

这段代码使用肘部法则和轮廓分数(silhouette score)来确定数据集的最佳分类数(簇数)。下面是对代码的详细解析:

导入必要的库

from sklearn.cluster import KMeans  
from sklearn.metrics import silhouette_score  

初始化变量

inertia = []  
silhouette_scores = []  
i_range = range(2, 11)  
  • inertia:用来存储不同簇数下的簇内误差平方和(SSE)。
  • silhouette_scores:用来存储不同簇数下的轮廓分数。
  • i_range:簇数的范围,从2到10(包括2和10)。

迭代不同的簇数

for i in i_range:  kmeans = KMeans(n_clusters=i, random_state=10).fit(new_stock)  inertia.append(kmeans.inertia_)  silhouette_scores.append(silhouette_score(new_stock, kmeans.labels_))  
  • for i in i_range:遍历簇数范围,从2到10。
  • kmeans = KMeans(n_clusters=i, random_state=10).fit(new_stock):为每个簇数创建并训练一个KMeans模型。
    • n_clusters=i:设置当前簇数。
    • random_state=10:设置随机种子,以确保结果可复现。
    • fit(new_stock):对数据集 new_stock 进行聚类训练。
  • inertia.append(kmeans.inertia_):将当前簇数下的簇内误差平方和(SSE)添加到 inertia 列表中。
  • silhouette_scores.append(silhouette_score(new_stock, kmeans.labels_)):计算当前簇数下的轮廓分数,并添加到 silhouette_scores 列表中。

输出结果

inertia, silhouette_scores  
  • 这将输出不同簇数下的簇内误差平方和(SSE)和轮廓分数。

肘部法则
肘部法则(Elbow Method)通过绘制簇数与SSE的关系图来帮助确定最佳簇数。最佳簇数通常是在SSE曲线开始明显变平的位置,即肘部位置。

轮廓分数
轮廓分数(Silhouette Score)用于评估聚类的质量,其值在-1到1之间。值越高表示聚类效果越好。通过比较不同簇数下的轮廓分数,可以选择分数最高的簇数作为最佳簇数。

总结
这段代码的目的是通过计算不同簇数下的簇内误差平方和(SSE)和轮廓分数,帮助选择数据集的最佳分类数。结合肘部法则和轮廓分数可以更全面地评估聚类效果,从而确定最合适的簇数。

# 4. 确定分类
plt.figure(figsize=(15,5))plt.subplot(1, 2, 1)
plt.plot(i_range, inertia, marker='o')plt.subplot(1, 2, 2)
plt.plot(i_range, silhouette_scores, marker='o')plt.tight_layout()
plt.show()# 左图在 2 到 5 的时候,曲线下降速率明显下降。
# 右图在 2,3,4,5 时,轮廓系数比较高。
# 结合两图,选择 3 作为聚类数。


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

# 5. 分类kmeans_final = KMeans(n_clusters=3, random_state=10).fit(new_stock)labels = kmeans_final.labels_
new_stock['cluster'] = labels
new_stock.head()
tradepricechangechangepercentbuysellsettlementopenhighlowvolumeamountperpbmktcapnmcturnoverratiocluster
010.890.100.92710.8810.8910.7910.9611.1110.8417841005719538174934.8400.5082.113304e+072.113264e+070.919382
17.460.050.6757.457.467.417.637.887.4452449378839969217037.2430.3558.900309e+067.248834e+065.397731
210.440.232.25310.4310.4410.219.9910.469.979885440102059842-8.8217.4781.382050e+051.318448e+057.827690
33.870.000.0003.873.883.873.964.013.862318718691348765-6.5090.7525.224481e+055.224451e+051.717590
44.09-0.15-3.5384.094.104.244.264.264.0424405501002858939.40311.2121.416972e+051.263597e+050.789950
查看分类结果
# 6. 查看分类情况new_stock['cluster'].value_counts()
cluster
0    4998
2     332
1      30
Name: count, dtype: int64
总结

KMeans 在确定分类个数计算时,无法使用 object 类型的数据,应当提前删除或对特征进行 one-hot 处理。

闯关题

STEP1:请根据要求完成题目

Q1. KMeans 中某个参数的含义是正确的?
A. n_clusters 分类个数
B. inertia_ 轮廓系数
C. silhouette_scores 曲线下降速率

Q2. 修改KMeans的划分集群个数为 4个,那么 002829 股票的分类是哪个?
A. 0
B. 1
C. 2
D. 3

kmeans_final2 = KMeans(n_clusters=4, random_state=10).fit(new_stock)labels = kmeans_final2.labels_
stock['cluster'] = labels
stock[stock['symbol'] == 'sz002829']['cluster']
1304    0
Name: cluster, dtype: int32

Q3. 前300个股票数据集划分集群的最优个数是多少?
A. 1
B. 3
C. 5
D. 10

new_stock = new_stock[0:300]inertia = []
silhouette_scores = []
i_range = range(2, 11)
for i in i_range:# 计算分类并保存指标kmeans = KMeans(n_clusters=i, random_state=10).fit(new_stock)inertia.append(kmeans.inertia_)silhouette_scores.append(silhouette_score(new_stock, kmeans.labels_))
inertia, silhouette_scores
([2.5308780913486823e+19,1.3473879858220839e+19,7.413489715471633e+18,6.109726555261718e+18,3.463054550988757e+18,2.604280833562603e+18,2.0732638975060705e+18,1.6982759851707302e+18,1.5100566906400458e+18],[0.8998406279029784,0.7527373456851054,0.692685627034619,0.6892926502877917,0.6522651603158817,0.6047949381607308,0.5696962854320331,0.5676513528559564,0.5655907482205398])
plt.figure(figsize=(15,5))plt.subplot(1, 2, 1)
plt.plot(i_range, inertia, marker='o')plt.subplot(1, 2, 2)
plt.plot(i_range, silhouette_scores, marker='o')plt.tight_layout()
plt.show()


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#填入你的答案并运行,注意大小写
a1 = 'A'  # 如 a1= 'A'
a2 = 'A'  # 如 a2= 'A'
a3 = 'B'  # 如 a3= 'A'

http://www.ppmy.cn/embedded/90250.html

相关文章

python dash框架

Dash 是一个用于创建数据分析型 web 应用的 Python 框架。它由 Plotly 团队开发&#xff0c;并且可以用来构建交互式的 web 应用程序&#xff0c;这些应用能够包含图表、表格、地图等多种数据可视化组件。 Dash 的特点&#xff1a; 易于使用&#xff1a;Dash 使用 Python 语法…

物联网项目——基于stm32的智能宠物喂食器

一、项目介绍&#xff1a; 智能宠物喂食器是一种通过嵌入式系统控制的设备&#xff0c;旨在为宠物提供自动化的喂食服务。基于 STM32 微控制器的智能宠物喂食器结合了精确的时间控制、用户友好的操作界面和灵活的喂食计划&#xff0c;使宠物主人能够远程管理和监控宠物的饮食。…

【Python系列】Python 字典合并

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Mongodb索引

MongoDB中的索引&#xff08;Indexes&#xff09;是为了加速查询而创建的数据结构。MongoDB的索引与关系数据库的索引类似&#xff0c;可以显著提高读取操作的性能。 mongodb中的索引概念 默认索引&#xff1a;MongoDB在每个集合上都会自动创建一个包含_id字段的唯一索引。自定…

图片转换之heic转jpg(使用ImageMagick)

缘由&#xff1a;iphone的图库&#xff0c;用jpg拍照保存后内存占比较大&#xff0c;heic格式会微缩不少。问题来了&#xff0c;电脑不能直接小图预览heic。 分析&#xff1a;现在就是解决小图预览的问题&#xff08;大图用wps可以看&#xff09; 解决&#xff1a;查找了一些…

【java计算机毕设】高校学生综合素质评价系统MySQL ssm JSP maven小组寒暑假项目设计源码代码作业

目录 1项目功能 2项目介绍 3项目地址 1项目功能 【java计算机毕设】高校学生综合素质评价系统MySQL ssm JSP maven小组寒暑假项目设计源码代码作业 2项目介绍 系统功能&#xff1a; 高校学生综合素质评价系统包括管理员、学生、教师三种角色。 管理员功能包括个人中心模块用…

微应用(Micro-Applications)、微前端(Micro Frontend)、Qiankun 框架之间的区别和联系

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo :联系我们:VX :tja6288 / EMAIL: 347969164@qq.com 文章目录 微应用(Micro-Applications)、微…

FIR低通滤波器

FIR低通滤波器 FIR(Finite Impulse Response)滤波器:有限长单位冲激响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。 MATLAB实现…