活动介绍

前端正则表达式 不能有汉字跟数字以外的数据 并且必须包含数字和字母 在vue3中如何实现

时间: 2024-09-27 21:12:33 浏览: 64
在 Vue.js 中,你可以使用正则表达式 (regex) 和 `v-model` 或者自定义的验证规则来检查输入字段的内容。这里是一个简单的例子,展示如何在 Vue 组件的 `<input>` 标签上使用正则表达式验证输入是否符合要求: ```html <template> <div> <input type="text" v-model="inputValue" @input="validateInput"> <p :class="{ invalid: hasInvalidInput }">输入无效</p> </div> </template> <script setup> import { ref, onMounted } from 'vue'; const inputValue = ref(''); const regexPattern = /^[a-zA-Z0-9]*$/; // 匹配只包含数字和字母的字符串 function validateInput() { const inputVal = inputValue.value; if (!regexPattern.test(inputVal)) { hasInvalidInput = true; } else { hasInvalidInput = false; } } onMounted(() => { validateInput(); // 初始验证 }) const hasInvalidInput = computed(() => !regexPattern.test(inputValue.value)); </script> <style scoped> .invalid { border-color: red; } </style> ``` 在这个示例中,当用户在输入框中输入内容时,`validateInput` 函数会被触发。如果输入不符合正则表达式的模式,`hasInvalidInput` 计算属性会变为 `true`,显示红色边框表示输入无效。
阅读全文

相关推荐

在我的后端中还有两个文件,一个是new_algorithm.py:import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.neural_network import MLPClassifier from sklearn.metrics import accuracy_score, classification_report from sklearn.preprocessing import StandardScaler from sklearn.pipeline import make_pipeline from sklearn.base import clone import matplotlib.pyplot as plt from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay import os import re from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer import seaborn as sns # 添加数据插补器 from sklearn.impute import SimpleImputer def check_chinese_font_support(): """检查系统是否支持中文字体""" chinese_fonts = ['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC', 'Microsoft YaHei', 'SimSun'] for font in chinese_fonts: try: plt.rcParams["font.family"] = font # 测试字体是否可用 fig, ax = plt.subplots(figsize=(1, 1)) ax.text(0.5, 0.5, '测试', fontsize=12) plt.close(fig) print(f"系统支持中文字体: {font}") return True except: continue print("系统不支持中文字体,将使用英文标签") plt.rcParams["font.family"] = ['Arial', 'sans-serif'] return False class GasSensorDataAnalyzer: """有害气体分类数据加载与预处理类""" def __init__(self): # 基础气体标签 self.gas_labels = { 'acetone': 0, 'toluene': 1, 'methanol': 2, 'formaldehyde': 3, 'ethanol': 4 } # 混合气体标签生成(每个混合气体用唯一数字标识) self.mixture_labels = self._generate_mixture_labels() # 合并所有气体标签 self.all_gas_labels = {**self.gas_labels, **self.mixture_labels} # 中英文气体名称映射 self.gas_names = { 'acetone': {'cn': '丙酮', 'en': 'Acetone'}, 'toluene': {'cn': '甲苯', 'en': 'Toluene'}, 'methanol': {'cn': '甲醇', 'en': 'Methanol'}, 'formaldehyde': {'cn': '甲醛', 'en': 'Formaldehyde'}, 'ethanol': {'cn': '乙醇', 'en': 'Ethanol'}, 'toluene+formaldehyde': {'cn': '甲苯+甲醛', 'en': 'Toluene+Formaldehyde'}, 'methanol+toluene+formaldehyde': {'cn': '甲醇+甲苯+甲醛', 'en': 'Methanol+Toluene+Formaldehyde'} # 可以根据需要添加更多混合气体的名称映射 } # 传感器类型映射 self.sensor_types = { 'MP2': 0, 'MP3B': 1, 'MP503': 2, 'MP801': 3, 'MQ2': 4, 'MQ7B': 5 } # 初始化多维度类别映射 self.multi_dimension_labels = {} self.next_label_id = 0 # 传感器中英文名称映射 self.sensor_names = { 'MP2': {'cn': 'MP2', 'en': 'MP2'}, 'MP3B': {'cn': 'MP3B', 'en': 'MP3B'}, 'MP503': {'cn': 'MP503', 'en': 'MP503'}, 'MP801': {'cn': 'MP801', 'en': 'MP801'}, 'MQ2': {'cn': 'MQ2', 'en': 'MQ2'}, 'MQ7B': {'cn': 'MQ7B', 'en': 'MQ7B'} } def _generate_mixture_labels(self): """生成混合气体的标签映射""" # 定义可能的混合气体组合 mixtures = [ 'toluene+formaldehyde', 'methanol+toluene+formaldehyde' # 可以根据需要添加更多混合气体组合 ] # 为每个混合气体分配唯一标签(从基础气体标签之后开始) next_label = max(self.gas_labels.values()) + 1 return {mixture: next_label + i for i, mixture in enumerate(mixtures)} def get_or_create_multi_dimension_label(self, sensor_type, gas_type, concentration): """ 获取或创建多维度类别标签 参数: - sensor_type: 传感器类型 - gas_type: 气体类型 - concentration: 浓度值 返回: - 标签ID和标签名称 """ # 创建唯一键 key = f"{sensor_type}_{gas_type}_{concentration}ppm" # 如果键不存在,创建新标签 if key not in self.multi_dimension_labels: self.multi_dimension_labels[key] = self.next_label_id self.next_label_id += 1 # 返回标签ID和标签名称 label_id = self.multi_dimension_labels[key] # 创建中英文标签名称 sensor_name_cn = self.sensor_names.get(sensor_type, {}).get('cn', sensor_type) sensor_name_en = self.sensor_names.get(sensor_type, {}).get('en', sensor_type) gas_name_cn = self.gas_names.get(gas_type, {}).get('cn', gas_type) gas_name_en = self.gas_names.get(gas_type, {}).get('en', gas_type) label_name_cn = f"{sensor_name_cn}_{gas_name_cn}_{concentration}ppm" label_name_en = f"{sensor_name_en}_{gas_name_en}_{concentration}ppm" return label_id, { 'cn': label_name_cn, 'en': label_name_en } def load_single_gas_data(self, file_path, gas_type, concentration, sensor_type): """ 加载单一气体数据 参数: - file_path: 文件路径 - gas_type: 气体类型 (如 'acetone', 'toluene' 等) - concentration: 浓度值 (如 20, 30, 50 等) - sensor_type: 传感器类型 (如 'MP2', 'MP801' 等) """ try: if not os.path.exists(file_path): raise FileNotFoundError(f"文件不存在: {file_path}") df = pd.read_excel(file_path, sheet_name='Sheet1', index_col=0) X = df.values # 尝试将数据转换为 float 类型 try: X = X.astype(float) except ValueError: print("警告: 数据中包含非数值类型,将过滤掉非数值类型的数据") numeric_mask = np.vectorize(np.isreal)(X) X = X[numeric_mask].reshape(-1, df.shape[1]) # 检查并报告NaN值 nan_count = np.isnan(X).sum() if nan_count > 0: print(f"警告: 数据中包含 {nan_count} 个NaN值") # 可选:替换NaN值为0 # X = np.nan_to_num(X, nan=0.0) # 创建多维度标签 label_id, label_name = self.get_or_create_multi_dimension_label( sensor_type, gas_type, concentration ) # 为所有样本分配相同的标签 y = np.full(len(X), label_id, dtype=int) print(f"已加载 {label_name['cn']} 数据: {len(X)} 样本, 特征维度: {X.shape[1]}") return X, y except Exception as e: print(f"加载数据时出错: {e}") return None, None def load_multiple_gas_data(self, file_paths, gas_types, concentrations, sensor_types): """ 加载多个气体数据并合并 参数: - file_paths: 文件路径列表 - gas_types: 气体类型列表 (如 ['acetone', 'toluene'] 等) - concentrations: 浓度值列表 (如 [20, 30] 等) - sensor_types: 传感器类型列表 (如 ['MP2', 'MP801'] 等) """ X_all = [] y_all = [] feature_dimensions = [] # 用于记录每个数据集的特征维度 for file_path, gas_type, concentration, sensor_type in zip( file_paths, gas_types, concentrations, sensor_types ): X, y = self.load_single_gas_data(file_path, gas_type, concentration, sensor_type) if X is not None and len(X) > 0: X_all.append(X) y_all.append(y) feature_dimensions.append(X.shape[1]) if not X_all: print("没有加载到有效数据") return None, None # 检查所有数据集的特征维度是否一致 unique_dimensions = np.unique(feature_dimensions) if len(unique_dimensions) > 1: print(f"警告: 检测到不同的特征维度: {unique_dimensions}") print("这可能导致合并数据时出错。请检查您的Excel文件是否具有相同的列数。") # 找出最常见的维度 from collections import Counter dimension_counts = Counter(feature_dimensions) most_common_dimension = dimension_counts.most_common(1)[0][0] print(f"最常见的特征维度是: {most_common_dimension}") # 过滤掉特征维度不匹配的数据 filtered_X_all = [] filtered_y_all = [] for i, X in enumerate(X_all): if X.shape[1] == most_common_dimension: filtered_X_all.append(X) filtered_y_all.append(y_all[i]) else: print(f"忽略特征维度不匹配的数据集: {file_paths[i]} (维度: {X.shape[1]})") if not filtered_X_all: print("没有找到特征维度匹配的数据集") return None, None X_all = filtered_X_all y_all = filtered_y_all # 合并所有数据 X_combined = np.vstack(X_all) y_combined = np.concatenate(y_all) # 检查合并后的数据中是否存在NaN值 total_nan = np.isnan(X_combined).sum() if total_nan > 0: print(f"警告: 合并后的数据中包含 {total_nan} 个NaN值,占比: {total_nan/(X_combined.size):.4f}") print(f"NaN值在样本中的分布: {np.isnan(X_combined).any(axis=1).sum()} 个样本包含NaN值") print(f"NaN值在特征中的分布: {np.isnan(X_combined).any(axis=0).sum()} 个特征包含NaN值") print(f"合并后的数据: {len(X_combined)} 样本,{len(np.unique(y_combined))} 个类别,特征维度: {X_combined.shape[1]}") return X_combined, y_combined def load_dataset(self, file_path, gas_type, concentration, sensor_type): """加载单一数据集并返回""" return self.load_single_gas_data(file_path, gas_type, concentration, sensor_type) class AlgorithmSelector: """多算法选择与训练类""" def __init__(self, use_chinese=True): # 算法名称映射 self.algorithm_names = { 'knn': {'cn': 'K-近邻算法', 'en': 'K-Nearest Neighbors'}, 'svm': {'cn': '支持向量机', 'en': 'Support Vector Machine'}, 'random_forest': {'cn': '随机森林', 'en': 'Random Forest'}, 'decision_tree': {'cn': '决策树', 'en': 'Decision Tree'}, 'neural_network': {'cn': '神经网络', 'en': 'Neural Network'} } # 算法配置 self.algorithms = { 'knn': { 'model': KNeighborsClassifier(), 'params': {'n_neighbors': 5, 'metric': 'euclidean'} }, 'svm': { 'model': SVC(), 'params': {'kernel': 'rbf', 'C': 1.0, 'probability': True} }, 'random_forest': { 'model': RandomForestClassifier(), 'params': {'n_estimators': 100, 'random_state': 42} }, 'decision_tree': { 'model': DecisionTreeClassifier(), 'params': {'max_depth': None, 'random_state': 42} }, 'neural_network': { 'model': MLPClassifier(), 'params': { 'neural_network__hidden_layer_sizes': (100, 50), # 注意前缀 'neural_network__max_iter': 500, 'neural_network__random_state': 42} } } # 算法是否需要标准化 self.needs_scaling = { 'knn': True, 'svm': True, 'random_forest': False, 'decision_tree': False, 'neural_network': True } # 是否使用中文 self.use_chinese = use_chinese def set_algorithm_params(self, algorithm_name, params): """设置算法参数""" if algorithm_name in self.algorithms: # 为Pipeline正确格式化参数名称 formatted_params = {f"{algorithm_name}__{k}": v for k, v in params.items()} self.algorithms[algorithm_name]['params'] = formatted_params else: raise ValueError(f"不支持的算法: {algorithm_name}") def train_models(self, X, y, test_size=0.2, random_state=42): """ 训练所有算法并返回结果 返回: - 包含训练好的模型及其性能的字典 """ # 检查类别数量 unique_classes = np.unique(y) num_classes = len(unique_classes) if num_classes < 2: print(f"警告: 数据集中只有 {num_classes} 个类别,某些算法可能无法训练") print(f"单一类别值: {unique_classes[0]}") # 跳过SVM算法,因为它需要至少两个类别 algorithms_to_train = [name for name in self.algorithms if name != 'svm'] print(f"由于单类别数据,将跳过 SVM 算法,仅训练: {', '.join([self.algorithm_names[name]['cn'] for name in algorithms_to_train])}") # 在单一数据集上划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=test_size, random_state=random_state ) # 标记这是单类别数据 is_single_class_data = True else: # 在多类别数据集上划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=test_size, random_state=random_state, stratify=y ) algorithms_to_train = list(self.algorithms.keys()) is_single_class_data = False # 检查数据类型并确保可以安全转换为数值类型 try: # 尝试将数据转换为float类型 X_train_numeric = X_train.astype(float) X_test_numeric = X_test.astype(float) # 检查训练数据中是否存在NaN值 train_nan = np.isnan(X_train_numeric).sum() if train_nan > 0: print(f"警告: 训练数据中包含 {train_nan} 个NaN值,占比: {train_nan/(X_train_numeric.size):.4f}") print(f"NaN值在训练样本中的分布: {np.isnan(X_train_numeric).any(axis=1).sum()} 个样本包含NaN值") print(f"NaN值在训练特征中的分布: {np.isnan(X_train_numeric).any(axis=0).sum()} 个特征包含NaN值") # 检查测试数据中是否存在NaN值 test_nan = np.isnan(X_test_numeric).sum() if test_nan > 0: print(f"警告: 测试数据中包含 {test_nan} 个NaN值,占比: {test_nan/(X_test_numeric.size):.4f}") print(f"NaN值在测试样本中的分布: {np.isnan(X_test_numeric).any(axis=1).sum()} 个样本包含NaN值") print(f"NaN值在测试特征中的分布: {np.isnan(X_test_numeric).any(axis=0).sum()} 个特征包含NaN值") except ValueError as e: print(f"警告: 无法将数据转换为数值类型,跳过NaN值检查: {e}") results = {} for name in algorithms_to_train: algo = self.algorithms[name] # 获取算法名称(根据是否支持中文选择) algo_name = self.algorithm_names[name]['cn'] if self.use_chinese else self.algorithm_names[name]['en'] try: print(f"\n训练 {algo_name}...") # 创建模型管道 if self.needs_scaling[name]: # 为需要标准化的算法创建包含三个步骤的Pipeline model = Pipeline([ ('imputer', SimpleImputer(strategy='mean')), # 使用均值填充缺失值 ('scaler', StandardScaler()), (name, clone(algo['model'])) ]) else: # 为不需要标准化的算法创建包含两个步骤的Pipeline model = Pipeline([ ('imputer', SimpleImputer(strategy='mean')), # 使用均值填充缺失值 (name, clone(algo['model'])) ]) # 为决策树和随机森林直接设置参数,不使用Pipeline参数设置方式 if name in ['decision_tree', 'random_forest']: # 获取算法实例 algo_instance = model.named_steps[name] # 直接设置参数 for param, value in algo['params'].items(): setattr(algo_instance, param, value) else: # 为其他算法使用Pipeline参数设置方式 model.set_params(**algo['params']) # 训练模型 model.fit(X_train, y_train) # 评估模型 train_accuracy = model.score(X_train, y_train) test_accuracy = model.score(X_test, y_test) y_pred = model.predict(X_test) print(f"训练集准确率: {train_accuracy:.4f}") print(f"测试集准确率: {test_accuracy:.4f}") print("分类报告:") print(classification_report(y_test, y_pred)) results[name] = { 'name': algo_name, 'model': model, 'train_accuracy': train_accuracy, 'test_accuracy': test_accuracy, 'y_pred': y_pred, 'X_test': X_test, 'y_test': y_test, 'unique_labels': np.unique(y_test), 'is_single_class': is_single_class_data } except Exception as e: print(f"训练 {algo_name} 时发生错误: {e}") results[name] = { 'name': algo_name, 'error': str(e), 'is_single_class': is_single_class_data } # 为跳过的SVM算法添加结果记录 if 'svm' not in algorithms_to_train: svm_name = self.algorithm_names['svm']['cn'] if self.use_chinese else self.algorithm_names['svm']['en'] results['svm'] = { 'name': svm_name, 'error': "由于单类别数据,跳过SVM算法", 'is_single_class': is_single_class_data } return results def compare_algorithms(self, results): """比较不同算法的性能""" # 过滤掉训练失败的算法 valid_results = {name: result for name, result in results.items() if 'test_accuracy' in result} if not valid_results: print("没有算法成功训练,无法生成比较图。") return None names = [valid_results[name]['name'] for name in valid_results] accuracies = [valid_results[name]['test_accuracy'] for name in valid_results] plt.figure(figsize=(12, 6)) bars = plt.bar(names, accuracies, color='skyblue') # 根据是否支持中文选择标题 title = "不同算法的测试集准确率比较" if self.use_chinese else "Comparison of Test Set Accuracies for Different Algorithms" x_label = "算法" if self.use_chinese else "Algorithm" y_label = "准确率" if self.use_chinese else "Accuracy" plt.ylim(0, 1.05) plt.title(title) plt.xlabel(x_label) plt.ylabel(y_label) # 添加数值标签 for bar in bars: height = bar.get_height() plt.text(bar.get_x() + bar.get_width()/2., height + 0.01, f'{height:.4f}', ha='center', va='bottom') plt.xticks(rotation=45, ha='right') plt.tight_layout() return plt def plot_confusion_matrix(self, results, gas_data_loader, use_chinese=True, rotate_labels=45, fig_width=12, fig_height=10, font_size=10): """ 绘制混淆矩阵 参数: - results: 包含算法结果的字典 - gas_data_loader: 气体数据加载器实例 - use_chinese: 是否使用中文 - rotate_labels: 标签旋转角度,默认为45度 - fig_width: 图形的宽度,默认为12 - fig_height: 图形的高度,默认为10 - font_size: 字体大小,默认为10 """ # 过滤掉训练失败的算法 valid_results = {name: result for name, result in results.items() if 'test_accuracy' in result} if not valid_results: print("没有算法成功训练,无法生成混淆矩阵。") return None # 获取所有算法中出现的唯一标签 all_unique_labels = set() for name, result in valid_results.items(): all_unique_labels.update(result['unique_labels']) all_unique_labels = sorted(list(all_unique_labels)) # 创建标签名称映射 label_names = [] for label in all_unique_labels: # 尝试查找对应的多维度标签名称 label_name = None for key, label_id in gas_data_loader.multi_dimension_labels.items(): if label_id == label: # 获取标签名称而不是标签ID label_name = gas_data_loader.get_or_create_multi_dimension_label( key.split('_')[0], # 传感器类型 key.split('_')[1], # 气体类型 int(key.split('_')[2].replace('ppm', '')) # 浓度值 )[1] # 获取第二个返回值,即标签名称字典 break # 如果找到,使用对应的标签名称 if label_name and isinstance(label_name, dict): if use_chinese: label_names.append(label_name.get('cn', f"类别 {label}")) else: label_names.append(label_name.get('en', f"Class {label}")) else: # 如果没有找到,使用默认标签名称 label_names.append(f"类别 {label}" if use_chinese else f"Class {label}") for name, result in valid_results.items(): plt.figure(figsize=(fig_width, fig_height)) cm = confusion_matrix(result['y_test'], result['y_pred'], labels=all_unique_labels) disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=label_names) disp.plot(cmap=plt.cm.Blues) # 根据是否支持中文选择标题 title = f"{result['name']} 混淆矩阵" if use_chinese else f"{result['name']} Confusion Matrix" # 如果是单类别数据,添加说明 if result.get('is_single_class', False): title += " (单类别数据)" plt.title(title) # 旋转x轴标签 plt.xticks(rotation=rotate_labels, ha='right', rotation_mode='anchor', fontsize=font_size) plt.yticks(fontsize=font_size) plt.tight_layout() return plt def detect_dataset_type(dataset_path): """ 自动检测数据集类型:单一数据集或多数据集文件夹 参数: - dataset_path: 数据集路径 返回: - dataset_type: 'single' 或 'multiple' - file_paths: 文件路径列表 - gas_types: 气体类型列表 - concentrations: 浓度值列表 - sensor_types: 传感器类型列表 """ # 检查路径是否存在 if not os.path.exists(dataset_path): raise FileNotFoundError(f"路径不存在: {dataset_path}") # 检查是文件还是文件夹 if os.path.isfile(dataset_path): # 单一文件处理 file_paths = [dataset_path] # 从文件名提取传感器类型、气体类型和浓度 file_name = os.path.basename(dataset_path) sensor_type = extract_sensor_type(file_name) gas_type = extract_gas_type(file_name) concentration = extract_concentration(file_name) gas_types = [gas_type] concentrations = [concentration] sensor_types = [sensor_type] print(f"检测到单一数据集: {file_name}") print(f"传感器类型: {sensor_type}, 气体类型: {gas_type}, 浓度: {concentration}ppm") return 'single', file_paths, gas_types, concentrations, sensor_types elif os.path.isdir(dataset_path): # 文件夹处理 - 查找所有Excel文件 excel_files = [f for f in os.listdir(dataset_path) if f.endswith(('.xlsx', '.xls'))] if not excel_files: raise ValueError(f"文件夹中没有找到Excel文件: {dataset_path}") file_paths = [] gas_types = [] concentrations = [] sensor_types = [] for file in excel_files: file_path = os.path.join(dataset_path, file) file_paths.append(file_path) # 从文件名提取传感器类型、气体类型和浓度 sensor_type = extract_sensor_type(file) gas_type = extract_gas_type(file) concentration = extract_concentration(file) gas_types.append(gas_type) concentrations.append(concentration) sensor_types.append(sensor_type) print(f"找到数据集文件: {file}") print(f"传感器类型: {sensor_type}, 气体类型: {gas_type}, 浓度: {concentration}ppm") print(f"总共找到 {len(file_paths)} 个数据集文件") return 'multiple', file_paths, gas_types, concentrations, sensor_types else: raise ValueError(f"无法识别的路径: {dataset_path}") def extract_sensor_type(file_name): """从文件名提取传感器类型""" # 定义传感器类型的正则表达式模式 sensor_patterns = { 'MP2': r'(^MP2[^a-zA-Z0-9]|MP2$)', 'MP3B': r'(^MP3B[^a-zA-Z0-9]|MP3B$)', 'MP503': r'(^MP503[^a-zA-Z0-9]|MP503$)', 'MP801': r'(^MP801[^a-zA-Z0-9]|MP801$)', 'MQ2': r'(^MQ2[^a-zA-Z0-9]|MQ2$)', 'MQ7B': r'(^MQ7B[^a-zA-Z0-9]|MQ7B$)' } # 转换为大写以提高匹配率 file_name_upper = file_name.upper() # 尝试匹配传感器类型 for sensor_type, pattern in sensor_patterns.items(): if re.search(pattern, file_name_upper): return sensor_type # 如果没有匹配到,返回默认值 print(f"警告: 无法从文件名 '{file_name}' 中提取传感器类型,使用默认值 'MP2'") return 'MP2' def extract_gas_type(file_name): """从文件名提取气体类型""" # 定义基础气体类型的中英文名称映射 gas_name_mapping = { 'bingtong': 'acetone', '丙酮': 'acetone', 'jiaben': 'toluene', '甲苯': 'toluene', 'jiachun': 'methanol', '甲醇': 'methanol', 'jiaquan': 'formaldehyde', '甲醛': 'formaldehyde', 'yichun': 'ethanol', '乙醇': 'ethanol' } # 去除文件扩展名 file_name_without_ext = os.path.splitext(file_name)[0] # 按照固定格式"传感器_气体名称_浓度"分割文件名 parts = file_name_without_ext.split('_') # 确保有足够的部分 if len(parts) < 3: print(f"警告: 文件名格式不符合预期: {file_name}") return 'acetone' # 获取气体名称部分 gas_name_part = parts[1] # 检查是否为混合气体 if '+' in gas_name_part or '+' in gas_name_part: # 处理混合气体 # 统一分隔符 gas_name_part = gas_name_part.replace('+', '+') gas_components = gas_name_part.split('+') # 转换为标准气体名称 standard_gas_names = [] for component in gas_components: # 先尝试中文名称映射 standard_name = gas_name_mapping.get(component, None) if standard_name: standard_gas_names.append(standard_name) else: # 如果是英文名称,直接添加 if component.lower() in ['acetone', 'toluene', 'methanol', 'formaldehyde', 'ethanol']: standard_gas_names.append(component.lower()) else: print(f"警告: 无法识别的气体成分: {component}") # 按字母顺序排序以确保一致性 standard_gas_names.sort() # 组合成混合气体名称 if len(standard_gas_names) > 1: return '+'.join(standard_gas_names) elif len(standard_gas_names) == 1: return standard_gas_names[0] # 处理单一气体 # 先尝试中文名称映射 standard_name = gas_name_mapping.get(gas_name_part, None) if standard_name: return standard_name # 如果是英文名称,直接返回小写形式 if gas_name_part.lower() in ['acetone', 'toluene', 'methanol', 'formaldehyde', 'ethanol']: return gas_name_part.lower() # 如果没有匹配到,返回默认值 print(f"警告: 无法从文件名 '{file_name}' 中提取气体类型,使用默认值 'acetone'") return 'acetone' def extract_concentration(file_name): """从文件名提取浓度值""" # 去除文件扩展名 file_name_without_ext = os.path.splitext(file_name)[0] # 按照固定格式"传感器_气体名称_浓度"分割文件名 parts = file_name_without_ext.split('_') # 确保有足够的部分 if len(parts) < 3: print(f"警告: 文件名格式不符合预期: {file_name}") return 20 # 获取浓度部分 concentration_part = parts[2] # 提取数字部分 match = re.search(r'(\d+)', concentration_part) if match: return int(match.group(1)) # 如果没有匹配到,返回默认值 print(f"警告: 无法从文件名 '{file_name}' 中提取浓度值,使用默认值 20ppm") return 20 def main(): """主函数""" # 检查中文字体支持 chinese_supported = check_chinese_font_support() # 创建数据加载器 data_loader = GasSensorDataAnalyzer() # 定义数据集路径 dataset_path = r"C:\Users\Cong\Desktop\作业\项目\六通道2混合\2_MP2" try: # 自动检测数据集类型 dataset_type, file_paths, gas_types, concentrations, sensor_types = detect_dataset_type(dataset_path) # 根据检测结果加载数据 if dataset_type == 'single': # 加载单一数据集 X, y = data_loader.load_dataset(file_paths[0], gas_types[0], concentrations[0], sensor_types[0]) else: # 加载多个数据集并合并 X, y = data_loader.load_multiple_gas_data(file_paths, gas_types, concentrations, sensor_types) if X is None or len(X) == 0: print("No valid data available for training. Please check file paths and formats.") return print(f"加载的数据集总样本数: {len(X)}") print(f"数据集中的类别数量: {len(np.unique(y))}") # 创建算法选择器,根据中文字体支持情况决定是否使用中文 selector = AlgorithmSelector(use_chinese=chinese_supported) # 自定义参数配置示例 selector.set_algorithm_params('knn', {'n_neighbors': 3, 'metric': 'manhattan'}) selector.set_algorithm_params('svm', {'C': 0.8, 'kernel': 'linear'}) selector.set_algorithm_params('neural_network', {'hidden_layer_sizes': (150, 75)}) # 训练所有算法 results = selector.train_models(X, y) # 比较算法性能 plt1 = selector.compare_algorithms(results) if plt1: plt1.savefig('algorithm_comparison.png') plt1.close() # 绘制混淆矩阵 plt2 = selector.plot_confusion_matrix(results, data_loader, use_chinese=chinese_supported, rotate_labels=45,fig_width=20, fig_height=20, font_size=8) if plt2: plt2.savefig('confusion_matrix.png') plt2.close() print("\n算法比较结果已保存为 'algorithm_comparison.png'") print("混淆矩阵已保存为 'confusion_matrix.png'") except Exception as e: print(f"程序执行过程中发生错误: {e}") if __name__ == "__main__": main()还有一个是tempcoderunnerfile.py文件:@app.route('/upload', methods=['POST']) def upload_file(): """处理文件上传""" if 'files' not in request.files: return jsonify({'error': 'No file part'}), 400 files = request.files.getlist('files') gas_type = request.form.get('gas_type', 'acetone') concentration = int(request.form.get('concentration', 20)) if not files or files[0].filename == '': return jsonify({'error': 'No selected file'}), 400 datasets = [] for file in files: if file and allowed_file(file.filename): # 保存临时文件 file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename) file.save(file_path) # 加载数据 data = data_loader.load_single_gas_data(file_path, gas_type, concentration) datasets.append(data) # 删除临时文件 os.remove(file_path) # 合并数据集 X, y = data_loader.combine_datasets(datasets) if X is None or len(X) == 0: return jsonify({'error': 'No valid data loaded'}), 400 # 保存合并后的数据 df = pd.DataFrame(X) df['label'] = y file_path = os.path.join(app.config['UPLOAD_FOLDER'], 'temp_data.xlsx') df.to_excel(file_path, index=False) return jsonify({ 'status': 'success', 'sample_count': len(X), 'feature_count': X.shape[1], 'gas_type': gas_type, 'concentration': concentration })请根据这两个文件重修修改app.py文件,确保他在algorithmselection呈现的页面中当我选择两个文件进入的时候能够分析数据

最新推荐

recommend-type

工具变量-5G示范城市DID(2014-2025).xlsx

详细介绍及样例数据:https://blog.csdn.net/T0620514/article/details/149811741
recommend-type

Python打造的Slaee管理系统升级版发布

由于提供的文件信息中,文件名《基于python的slaee管理系统 (15).zip》与描述《基于python的slaee管理系统 (15).zip》相同,并且给出的压缩包文件名称列表中只有一个文件《基于python的slaee管理系统 (14).zip》,该信息表明我们正在讨论两个不同版本的Python系统管理软件的压缩包。以下知识点将根据这些信息详细展开: 知识点一:Python编程语言基础 Python是一种高级编程语言,以其简洁的语法和强大的库支持而闻名。它是解释型语言,具有动态类型系统和垃圾回收功能,适用于多种编程范式,包括面向对象、命令式、函数式和过程式编程。Python广泛应用于系统管理、网络服务器、开发脚本、科学计算、数据挖掘和人工智能等领域。 知识点二:系统管理相关知识 系统管理指的是对计算机系统进行配置、监控和维护的过程,包括硬件资源、软件资源和数据资源的管理。在Python中,系统管理通常涉及操作系统级别的任务,如进程管理、文件系统管理、网络配置、系统日志监控等。Python的系统管理库(例如psutil、fabric、paramiko等)提供了丰富的API来简化这些任务。 知识点三:项目版本控制 从文件名《基于python的slaee管理系统 (14).zip》和《基于python的slaee管理系统 (15).zip》可以看出,这是一个项目在不同版本之间的迭代。版本控制是一种记录一个或多个文件随时间变化的方式,它允许用户可以回到特定版本。在软件开发中,版本控制非常重要,它有助于团队协作、代码合并、分支管理和错误跟踪。常见的版本控制系统包括Git、Subversion (SVN)、Mercurial等。 知识点四:打包与部署 提到“压缩包子文件”,这通常意味着文件已经被压缩打包成一个ZIP文件。在软件开发中,打包是为了便于文件传输、存档保存和分发。在Python项目中,打包也是部署过程的一部分。一个Python项目通常需要包含源代码、依赖关系、配置文件和安装脚本等。打包成ZIP文件后,可以通过各种方式部署到服务器上运行,如使用Fabric或Ansible等自动化部署工具。 知识点五:项目命名及版本命名规则 文件命名中的“基于python的slaee管理系统”表明这是一个与Python语言相关的系统管理项目。而数字“15”和“14”则代表着项目的版本号,这表明项目在持续发展,不同的数字代表了项目在不同时期的迭代。版本号的命名规则通常遵循语义化版本控制(SemVer),这种版本控制系统以 MAJOR.MINOR.PATCH 的形式表示版本号。 知识点六:文件压缩与解压缩技术 ZIP是一种常用的文件压缩格式,它通过减少文件大小来提高存储效率和传输速度。ZIP文件通常是无损压缩,意味着文件在压缩和解压缩的过程中不会丢失信息。Python标准库提供了zipfile模块,允许用户在Python程序中创建ZIP文件、读取ZIP文件内容、提取ZIP文件中的文件等操作。用户可以使用各种图形界面工具(如WinRAR、7-Zip)或命令行工具来处理ZIP文件。 总结以上内容,从文件信息中我们可以得知该内容涉及了Python编程语言、系统管理知识、版本控制、打包与部署、命名规则以及文件压缩技术等多方面的知识点。这些知识点对于理解和应用Python进行系统管理软件开发以及软件的版本迭代、打包与部署均具有重要意义。
recommend-type

深入解析PCB走线传输延时:关键因素与实用公式

# 1. PCB走线传输延时基础 在电子工程领域,尤其是在印刷电路板(PCB)设计中,走线传输延时是一个不可忽视的重要概念。传输延时主要指的是电信号通过PCB上的导电路径从源头传送到目的地所耗费的时间。本章将介绍PCB走线传输延时的基础知识点,为后续章节的深入探讨打下坚实的基础。 首先,了解什么是传输延时是至关重要的。简单来说,它反
recommend-type

gpio很弱是什么意思

<think>嗯,用户的问题是关于GPIO信号弱的概念及其影响。用户似乎对硬件或嵌入式系统有一定了解,但需要更深入的解释。从用户提到的"信号弱"来看,ta可能遇到了实际电路设计中的驱动能力问题,或者在学习GPIO原理时遇到了术语困惑。 用户引用了四篇资料,其中提到GPIO的模拟输入输出模式、施密特触发器的作用、上拉下拉电阻的配置,以及信号线串联电阻的作用。这些内容都与GPIO的驱动能力和信号质量相关。特别是引用[4]中提到的"信号线串联小电阻"和"低频电路不考虑反射",暗示用户可能正在处理实际电路中的信号完整性问题。 用户真正想知道的可能是:为什么我的GPIO输出无法正确驱动某个设备?或者
recommend-type

Python打造的Slaee管理系统升级版发布

标题中的“基于python的slaee管理系统”表明这是一个使用Python编程语言开发的系统。Python是一种广泛使用的高级编程语言,以其易读性和简洁的语法而闻名。SLAEE管理系统可能是指一个特定类型的管理软件,但由于没有给出缩写的完整解释,我们可以假设SLAEE可能是某机构或系统名称的缩写。 从标题和描述来看,存在一处笔误:“基于python的slaee管理系统 (19).zip”和“基于python的slaee管理系统 (18).zip”所指的似乎是同一软件系统,只是版本号不同。根据文件名称列表中的两个文件名,可以推断系统至少有两个版本,一个是版本18,一个是版本19。通常情况下,版本号的增加表示软件进行了更新或改进。 接下来,根据这些信息,我们可以阐述一些相关的知识点: 1. Python编程基础:Python是一种解释型、面向对象、高级编程语言。Python支持多种编程范式,包括过程式、面向对象和函数式编程。Python由于其简洁和易于学习的特性,被广泛应用于网络开发、数据分析、人工智能、机器学习和科学计算等领域。 2. 文件压缩与打包:文件压缩是将文件的大小减小以节省存储空间或网络传输时间的技术。常见的文件压缩格式包括ZIP、RAR、7Z等。文件打包通常指的是将多个文件或文件夹压缩成一个单独的文件。这在数据备份、软件分发和档案管理中非常常见。 3. 版本控制:在软件开发中,“版本”通常指软件的特定状态,版本号则用来标识这些状态。版本控制是一种记录文件、目录或集合随着时间变化的方式,以便将来可以检索特定版本。对于软件项目来说,版本控制是至关重要的,它不仅允许开发者追踪和管理代码的变化,而且还能帮助团队协作,解决冲突,并回滚到旧版本。 4. 软件管理系统的开发:一个软件管理系统可能是针对特定业务领域而设计的,它可能包括用户界面、数据库管理、业务逻辑处理、报告生成和其他许多功能。软件管理系统的开发通常涉及需求分析、系统设计、编程、测试和维护等多个阶段。 5. Python在软件开发中的应用:Python因为具有丰富的库和框架,被广泛用于开发各种类型的软件。例如,Django和Flask是用于Web开发的流行Python框架;而对于数据分析和数据科学任务,Pandas、NumPy和Matplotlib等库提供了强大的数据处理和可视化工具;对于机器学习和人工智能,TensorFlow、PyTorch等库使得复杂算法的实现变得更为简单。 6. 系统更新与维护:随着软件的使用和发展,需求可能会变化,新的问题可能会出现,所以软件系统需要定期进行更新和维护。软件更新可能包括修复已知问题、改进现有功能、增加新功能或优化性能。开发者需要评估是否需要为修复安全漏洞或提高系统性能而更新系统,以及更新之后对用户体验的影响。 由于文件名中只提到了“基于python的slaee管理系统”,没有提供该系统具体功能的详细描述,我们无法提供更加具体的技术知识点。如果需要分析系统的工作原理或具体的技术实现细节,还需要更多的信息。
recommend-type

【Keil-ARM编程艺术】:如何编写可维护且高效的代码

# 摘要 本文旨在为读者提供ARM微控制器编程和Keil开发环境的全面指南。第一章概览了ARM微控制
recommend-type

应用层协议概述

<think>首先,用户的问题是:“我想了解应用层协议的基本概念和常见类型 请问应用层协议简介 常见应用层协议概述”。这翻译成:“I want to understand the basic concepts of application layer protocols and common types. Please introduce application layer protocols and overview common application layer protocols.” 根据系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式使用$$...$$格式
recommend-type

Delphi 12 TeeChartVCLFMX控件包下载及功能介绍

标题中提到的"Delphi 12 控件之TeeChartVCLFMX-2024.40.rar"指的是Delphi 12版本中使用的TeeChartVCLFMX图表控件的特定版本(2024.40版本)。Delphi是由Embarcadero Technologies开发的一款流行的集成开发环境(IDE),专门用于使用Object Pascal和C++语言开发软件应用程序。该标题强调了Delphi 12环境下TeeChartVCLFMX控件的使用,这表明Delphi的图形用户界面(GUI)组件库中包含了一个专门用于创建复杂图表和图形的组件。 从描述中仅能得到的关于文件的名称是"TeeChartVCLFMX-2024.40.rar",这意味着文件是一个压缩包,具体包含了一个TeeChartVCLFMX的图表控件,版本号为2024.40。它可能包含了在Delphi 12版本中使用该图表控件所需的所有文件,包括库文件、二进制文件、文档等。 标签"delphi 控件"简单而直接地指出了该文件属于Delphi编程环境中的一个控件类别,表明了目标用户是Delphi开发者,他们通常使用这些控件来丰富他们的应用程序界面或增强应用程序的功能。 文件名称列表提供了关于TeeChartVCLFMX压缩包内包含的具体文件及其用途的详细信息: 1. TeeChartVCLFMX-2024.40.exe:这个文件很可能是一个安装程序或可执行文件,用于安装或运行TeeChartVCLFMX图表控件。 2. Keygen.exe:这个文件名表明它可能是一个密钥生成器(Key Generator),用于生成软件的注册码或激活码,使得控件可以脱离试用限制或进行合法授权。 3. Delphi29Binaries-2024.40-windows.pak:这个文件名暗示它包含了特定于Windows平台的Delphi 29(可能指的是Delphi 12的内部版本号)的二进制文件。pak文件是压缩包的一种格式,可能包含了运行TeeChartVCLFMX图表控件所需的库文件、DLLs、组件文件等。 4. TeeChartVCLFMX-2024.40 - D12.pdf:这是一个PDF格式的文件,很可能是用户手册或帮助文档,提供了对TeeChartVCLFMX图表控件版本2024.40在Delphi 12中的使用说明,安装指南,功能介绍或示例代码等。 综合以上信息,可以推断TeeChartVCLFMX-2024.40压缩包是为Delphi 12的开发人员提供了一个专业的图表解决方案,使得用户能够将图表功能集成到他们用Delphi开发的应用程序中。TeeChartVCLFMX可能包含各种图表类型(如条形图、折线图、饼图等),以及丰富的定制选项,如颜色、样式、图例、数据绑定、交互式功能等。开发者可以利用TeeChartVCLFMX提供的图表控件在应用程序中创建强大的数据可视化功能,这对数据分析、科学计算、商业智能、财务报告等领域特别有用。 开发者需要使用Delphi 12 IDE配合提供的组件安装程序或执行文件安装和配置TeeChartVCLFMX控件,通过阅读PDF文档来了解如何使用控件,并在需要时使用Keygen.exe激活控件。Delphi29Binaries-2024.40-windows.pak文件可能包含了控件运行所需的核心二进制组件。通过合理使用这些资源,开发者可以将TeeChartVCLFMX控件集成到自己的项目中,快速构建功能丰富的图表和数据可视化组件。
recommend-type

【Keil-ARM性能优化全解】:代码监控与优化工具的实用技巧

# 摘要 本文对基于Keil-ARM平台的性能优化进行了系统性探讨,涵盖了性能监控工具的介绍、代码优化策略、系统资源管理以及综合案例分析。首先,介绍了Keil-ARM的性能监控工具及其在性能分析中的重要性,包括工具的配置和性能数据解读方法。其次,文中讨论了代码层面的优化,包括高效循环和条件语句的编写,函数内联与尾调用优化,以及编译器优化选项的应用。然后,深入分析了ARM系统资源分配、
recommend-type

电子邮箱协议

<think>首先,用户的问题是:“我想了解电子邮箱相关的协议 请问电子邮件协议有哪些”。这直接询问电子邮件协议的种类。 从系统级指令中,我需要: - 使用中文回答。 - 结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 - 在行内数学表达式使用 $...$,但这里可能没有数学内容。 - 独立公式使用 $$...$$,但可能不需要。 - 生成相关问题。 - 在引用的段落末尾添加引用标识如 [^1]。 参考提供的引用: - 引用[1]: 讨论了SMTP、POP3和IMAP。 - 引用[2]: 提到电子邮件系统采用客户机/服务器模式,涉及接收和发送邮件。 - 引用[3]: 详细描述了P