AI赛事比分分析项目遇ValueError:输入含NaN等非法浮点值
问题解决与KNN实现方案
一、解决ValueError: Input contains NaN...错误
这个错误源于数据集存在缺失值(NaN)、无穷大值或超出float64范围的数据,处理步骤如下:
- 检查数据异常
加载数据后先排查异常情况:
import pandas as pd import numpy as np data = pd.read_csv('C:/Users/erdi/Desktop/son20yil/STSL_yeni.csv') # 查看各列缺失值数量 print(data.isnull().sum()) # 查看数值型列的统计分布,排查异常值 print(data.describe()) # 检查是否存在无穷大值 print(np.isinf(data.select_dtypes(include=[np.number])).sum())
- 清洗数据
根据检查结果针对性处理:
- 缺失值较少时,直接删除含缺失值的行:
data = data.dropna() - 缺失值较多时,用列的中位数填充(避免均值受极端值影响):
numeric_cols = data.select_dtypes(include=[np.number]).columns data[numeric_cols] = data[numeric_cols].fillna(data[numeric_cols].median()) - 移除无穷大值:
data = data.replace([np.inf, -np.inf], np.nan).dropna()
二、基于KNN算法实现赛事比分分析
我们用KNN回归模型预测两队的预期进球数,进而推导比分结果。核心逻辑是:用球队历史场次、失球、胜平负、积分等数据作为特征,训练模型预测单队的进球能力,结合两队数据生成比分预测。
完整代码实现
import pandas as pd import numpy as np from sklearn.neighbors import KNeighborsRegressor from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 1. 数据加载与清洗 data = pd.read_csv('C:/Users/erdi/Desktop/son20yil/STSL_yeni.csv') # 替换无穷值为NaN,再用中位数填充数值型列 data = data.replace([np.inf, -np.inf], np.nan) numeric_cols = ['MacSayisi', 'AtGol', 'YeGol', 'Galibiyet', 'Beraberlik', 'Maglubiyet', 'Puan'] data[numeric_cols] = data[numeric_cols].fillna(data[numeric_cols].median()) # 确保队名无缺失 data = data.dropna(subset=['TakimAdi']) # 2. 定义特征与目标变量 # 用球队历史数据训练模型,预测单队的进球数(AtGol) features = data[['MacSayisi', 'YeGol', 'Galibiyet', 'Beraberlik', 'Maglubiyet', 'Puan']] target = data['AtGol'] # 3. 特征标准化(KNN对尺度敏感,必须执行) scaler = StandardScaler() features_scaled = scaler.fit_transform(features) # 4. 划分训练测试集 X_train, X_test, y_train, y_test = train_test_split(features_scaled, target, test_size=0.2, random_state=42) # 5. 构建并训练KNN模型 knn_model = KNeighborsRegressor(n_neighbors=5) # k值可通过交叉验证优化 knn_model.fit(X_train, y_train) # 6. 预测指定两队的比分 takim1_adi = "BESIKTAS" takim2_adi = "FENERBAHCE" # 获取两队历史数据的均值(代表球队平均水平) takim1_stats = data[data['TakimAdi'] == takim1_adi][numeric_cols].mean().values takim2_stats = data[data['TakimAdi'] == takim2_adi][numeric_cols].mean().values # 提取用于预测的特征(排除目标变量AtGol) takim1_input = takim1_stats[[0,2,3,4,5,6]] # 对应MacSayisi, YeGol, Galibiyet, Beraberlik, Maglubiyet, Puan takim2_input = takim2_stats[[0,2,3,4,5,6]] # 标准化输入特征 takim1_input_scaled = scaler.transform(takim1_input.reshape(1, -1)) takim2_input_scaled = scaler.transform(takim2_input.reshape(1, -1)) # 预测预期进球数并取整 takim1_goals = round(knn_model.predict(takim1_input_scaled)[0]) takim2_goals = round(knn_model.predict(takim2_input_scaled)[0]) print(f"{takim1_adi} vs {takim2_adi} 预测比分: {takim1_goals} - {takim2_goals}")
关键说明
- 特征标准化:KNN基于距离计算,特征尺度差异会干扰结果,必须用
StandardScaler统一尺度。 - k值优化:代码中默认用
n_neighbors=5,可通过交叉验证找到最优值:from sklearn.model_selection import GridSearchCV param_grid = {'n_neighbors': range(3,10)} grid = GridSearchCV(KNeighborsRegressor(), param_grid, cv=5) grid.fit(X_train, y_train) print("最优k值:", grid.best_params_['n_neighbors']) - 比分优化:若需要更精准的胜负结果,可改用KNN分类模型,将目标变量设为比赛胜负标签(需补充对应数据)。
内容的提问来源于stack exchange,提问作者erdi
相关产品推荐
相关产品推荐

