当前位置: 首页 > news >正文

机器学习-人与机器生数据的区分模型测试-数据处理1

附件为训练数据,总体的流程可以作为参考。

导入依赖

import pandas as pd
import os
import numpy as np
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.ensemble import RandomForestClassifier,VotingClassifier 
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix,roc_curve
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from lightgbm import LGBMClassifier
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler,LabelEncoder
from catboost import CatBoostClassifier
from statsmodels.stats.outliers_influence import variance_inflation_factor
# 分析高频共现特征组合
from mlxtend.frequent_patterns import apriori
from sklearn.metrics import roc_auc_score
import json
# 设置工作目录
os.chdir(r'D:\python code\人工与机器人识别')
# 加载数据集
data = pd.read_csv('bots_vs_users.csv')  # 替换为你的数据集路径

EDA

数据分布

def clean_data(data):for col in data.columns:print(col)if col == 'city':  # 跳过第一列continueelse:    data[col] = data[col].replace('Unknown','-1')  # 使用均值填充缺失值data[col] = data[col].astype('float64')  # 转换为数值类型data[col] = data[col].fillna(data[col].mean())  # 使用均值填充缺失值return datadata = clean_data(data)encoder = LabelEncoder()
encoder.fit(data['city'])  # 只在第一个DF上fit
data['city2'] = encoder.transform(data['city'])# 第一次拆分:训练集(70%) + 临时集(30%), 
data,temp = train_test_split(data, test_size=0.1, random_state=42)# 输出拆分后的数据集大小
print("训练集大小:", data.shape)
print("验证集大小:", temp.shape)
print(data.head())

这里是数据的相关描述统计

入图片描述

描述统计

# 训练集编码
target_list = ['city', 'target', 'city2']
data_clean = data.drop(target_list, axis=1).copy()# 基本统计描述
print(data_clean.describe().T)print("方差:\n", data_clean.var(numeric_only=True))
print("众数:\n", data_clean.mode().T) 
print("偏度:\n", data_clean.skew(numeric_only=True))  # 需确保数据为数值型
print("峰度:\n", data_clean.kurtosis(numeric_only=True))

查看数据的分布情况
在这里插入图片描述


def plot_cont_var_dist(df, feature, target='target'):"""绘制连续变量的正负样本核密度估计图(KDE),并计算并标注 KS(Kolmogorov-Smirnov)统计量。参数:df (pandas.DataFrame): 包含特征和目标变量的数据集。feature (str): 要绘制的连续特征的名称。target (str, 可选): 目标变量的名称,默认为 'target'。"""# 设置图形的大小plt.figure(figsize=(10,6))# 提取正样本数据,并处理无穷大值,移除缺失值pos_data = df.loc[df[target]==1, feature].replace([np.inf, -np.inf], np.nan).dropna()# 提取负样本数据,并处理无穷大值,移除缺失值neg_data = df.loc[df[target]==0, feature].replace([np.inf, -np.inf], np.nan).dropna()# 绘制正样本的核密度估计图sns.kdeplot(pos_data, label='Positive', fill=True, alpha=0.5, color='#FF6B6B')# 绘制负样本的核密度估计图sns.kdeplot(neg_data, label='Negative',fill=True, alpha=0.5, color='#4ECDC4')# 检查正样本或负样本数据是否为空,如果为空则跳过该特征的绘制if pos_data.empty or neg_data.empty:print(f"Skipped {feature} due to empty data")plt.close()returntry:# 计算 ROC 曲线所需的假正率、真正率和阈值# 由于使用连续变量计算 KS 需要离散化处理,这里借助 roc_curve 函数fpr, tpr, thresholds = roc_curve(df[target], df[feature])# 计算 KS 统计量,即真正率与假正率差值的最大值ks_value = max(tpr - fpr)# 找到对应 KS 统计量最大值的阈值ks_threshold = thresholds[np.argmax(tpr - fpr)]except Exception as e:# 若计算 KS 统计量时出错,打印错误信息并关闭图形print(f"Error calculating KS for {feature}: {str(e)}")plt.close()return# 在图中绘制 KS 阈值对应的垂直线plt.axvline(ks_threshold, color='#2A363B', linestyle='--', linewidth=1.5, label=f'Cutoff: {ks_threshold:.2f}')# 设置图形标题,包含特征名称和 KS 统计量的值plt.title(f'{feature}\nKS Statistic = {ks_value:.2f}', fontsize=14)# 设置 x 轴标签plt.xlabel(feature, fontsize=12)# 设置 y 轴标签plt.ylabel('Density', fontsize=12)# 显示图例,去掉边框plt.legend(frameon=False)# 自动调整子图参数,使之填充整个图像区域plt.tight_layout()# 显示图形plt.show()# 关闭图形,释放内存plt.close()# 改进后的过滤逻辑
def is_valid_numeric(col_data):"""判断传入的列数据是否为有效的数值型特征。有效的数值型特征需满足以下条件:1. 数据类型为数值类型。2. 唯一值的数量超过 20 个。3. 数据类型不是分类类型。参数:col_data (pandas.Series): 需要进行判断的列数据。返回:bool: 如果满足所有条件则返回 True,否则返回 False。"""return (# 检查数据类型是否为数值类型pd.api.types.is_numeric_dtype(col_data) and # 检查唯一值的数量是否超过 20 个col_data.nunique() > 20 and# 检查数据类型是否不是分类类型not isinstance(col_data.dtype, pd.CategoricalDtype))filtered_list = [col for col in data.columns if col not in target_list and is_valid_numeric(data[col])]# 增强型绘图循环
for col in filtered_list:try:# 预处理inf值data[col] = data[col].replace([np.inf, -np.inf], np.nan)# 跳过缺失率过高的特征if data[col].isnull().mean() > 0.8:print(f"Skipped {col} due to high missing rate")continueplot_cont_var_dist(data, col)except Exception as e:print(f"Plotting failed for {col}: {str(e)}")#查看数据1的分布情况
one_ratio_list = []
for col in data.columns:if col == 'city' or col == 'target' or col == 'city2':  # 跳过第一列continueelse:one_ratio = data[col].mean()  # 计算1值占比print(f"{col}: {one_ratio}")one_ratio_list.append(one_ratio)plt.figure(figsize=(8,4))
sns.histplot(one_ratio_list, bins=20, kde=True)
plt.title('Histogram of 1-Value Proportion Distribution')
plt.xlabel('Proportion of 1 value')
plt.show()

上述代码会输出相关数据的分布图片,数据很多不一一展示。
在这里插入图片描述

相关文章:

  • JavaScript 的编译与执行原理
  • 基于Fashion-MNIST的softmax回归-直接运行
  • 第3章 自动化测试:从单元测试到硬件在环(HIL)
  • 电子电路:到底该怎么理解电容器的“通交流阻直流”?
  • ElasticSearch 8.x新特性面试题
  • 使用Maven部署WebLogic应用
  • Ubuntu 添加系统调用
  • React中useDeferredValue与useTransition终极对比。
  • Spring-boot初次使用
  • redis的pipline使用结合线程池优化实战
  • 精益数据分析(63/126):移情阶段的深度潜入——从用户生活到产品渗透的全链路解析
  • linux——mysql高可用
  • 用 CodeBuddy 打造我的「TextBeautifier」文本美化引擎
  • SEO 优化实战:ZKmall模板商城的 B2C商城的 URL 重构与结构化数据
  • Webpack DefinePlugin插件介绍(允许在编译时创建JS全局常量,常量可以在源代码中直接使用)JS环境变量
  • TCP/UDP协议原理和区别 笔记
  • RAGFlow Arbitrary Account Takeover Vulnerability
  • python的漫画网站管理系统
  • 目标检测工作原理:从滑动窗口到Haar特征检测的完整实现
  • 现代健康养生新风尚
  • 北斗系统全面进入11个国际组织的标准体系
  • 第十一届世界雷达展开幕,尖端装备、“大国重器”集中亮相
  • 没有握手,采用翻译:俄乌三年来首次直接会谈成效如何?
  • 精品消费“精”在哪?多在体验上下功夫
  • 梅花奖在上海|湘剧《夫人如见》竞梅,长沙文旅来沪推广
  • 德州国资欲退出三东筑工,后者大股东系当地房企东海集团