Spaces:
Sleeping
Sleeping
| import pandas as pd | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import seaborn as sns | |
| from feature_extractor import RussianFeatureExtractor | |
| import os | |
| import sys | |
| import subprocess | |
| import traceback | |
| from sklearn.feature_extraction.text import TfidfVectorizer | |
| from sklearn.metrics.pairwise import cosine_similarity | |
| import re | |
| def check_environment(): | |
| """Проверка окружения и зависимостей""" | |
| print("=== ПРОВЕРКА ОКРУЖЕНИЯ ===") | |
| # Проверка пакетов | |
| packages = ['pandas', 'numpy', 'matplotlib', 'seaborn', 'scikit-learn', 'torch'] | |
| for package in packages: | |
| try: | |
| __import__(package) | |
| print(f"✅ {package}") | |
| except ImportError as e: | |
| print(f"❌ {package}: {e}") | |
| # Проверка Java | |
| try: | |
| subprocess.run(['java', '-version'], capture_output=True, check=True) | |
| print("✅ Java установлена") | |
| except: | |
| print("❌ Java не установлена - грамматический анализ не будет работать") | |
| def load_and_analyze_dataset(): | |
| """Загрузка и анализ структуры данных""" | |
| print("\n=== АНАЛИЗ ДАННЫХ ===") | |
| try: | |
| # Пробуем разные варианты загрузки | |
| for filename in ['small.csv', 'dataset.csv', 'train.csv']: | |
| if os.path.exists(filename): | |
| print(f"Найден файл: {filename}") | |
| # Пробуем разные разделители | |
| for delimiter in [';', ',', '\t']: | |
| try: | |
| df = pd.read_csv(filename, encoding='utf-8', delimiter=delimiter) | |
| if len(df.columns) > 1: # Успешная загрузка | |
| print(f"✅ Успешно загружен с разделителем '{delimiter}'") | |
| break | |
| except: | |
| continue | |
| else: | |
| print("❌ Не удалось определить разделитель") | |
| return None | |
| print(f"Размер данных: {df.shape[0]} строк, {df.shape[1]} колонок") | |
| print(f"Колонки: {df.columns.tolist()}") | |
| # Анализ содержания | |
| print("\n--- СТРУКТУРА ДАННЫХ ---") | |
| for col in df.columns: | |
| print(f"{col}: {df[col].dtype}, пропусков: {df[col].isnull().sum()}") | |
| if df[col].dtype == 'object': | |
| sample = df[col].iloc[0] if not df[col].isnull().all() else "N/A" | |
| print(f" Пример: {str(sample)[:100]}...") | |
| # Поиск ключевых колонок | |
| question_cols = [col for col in df.columns if 'вопрос' in col.lower()] | |
| transcript_cols = [col for col in df.columns if 'транскрипт' in col.lower()] | |
| score_cols = [col for col in df.columns if 'оценк' in col.lower() or 'балл' in col.lower()] | |
| print(f"\n--- ВЫЯВЛЕННЫЕ КОЛОНКИ ---") | |
| print(f"Вопросы: {question_cols}") | |
| print(f"Транскрипты: {transcript_cols}") | |
| print(f"Оценки: {score_cols}") | |
| return df | |
| print("❌ Не найден файл с данными") | |
| return None | |
| except Exception as e: | |
| print(f"❌ Ошибка загрузки данных: {e}") | |
| return None | |
| def test_alternative_features(texts): | |
| """Тест альтернативных методов извлечения признаков""" | |
| print("\n=== ТЕСТ АЛЬТЕРНАТИВНЫХ ПРИЗНАКОВ ===") | |
| features_list = [] | |
| for i, text in enumerate(texts): | |
| if pd.isna(text): | |
| features_list.append({}) | |
| continue | |
| text_str = str(text) | |
| features = {} | |
| # Базовые текстовые метрики | |
| features['text_length'] = len(text_str) | |
| words = re.findall(r'\b[а-яёa-z]+\b', text_str.lower()) | |
| features['word_count'] = len(words) | |
| sentences = re.split(r'[.!?]+', text_str) | |
| features['sentence_count'] = len([s for s in sentences if len(s.strip()) > 10]) | |
| features['avg_word_length'] = np.mean([len(w) for w in words]) if words else 0 | |
| features['lexical_diversity'] = len(set(words)) / len(words) if words else 0 | |
| # Стилистические особенности | |
| features['has_questions'] = int('?' in text_str) | |
| features['has_exclamations'] = int('!' in text_str) | |
| features['has_ellipsis'] = int('...' in text_str) | |
| # Сложность текста | |
| long_words = [w for w in words if len(w) > 6] | |
| features['long_word_ratio'] = len(long_words) / len(words) if words else 0 | |
| features_list.append(features) | |
| if i < 3: # Показать пример для первых 3 текстов | |
| print(f"Пример {i + 1}: {text_str[:80]}...") | |
| for k, v in features.items(): | |
| print(f" {k}: {v:.3f}") | |
| return pd.DataFrame(features_list) | |
| def enhanced_feature_extraction(df): | |
| """Улучшенное извлечение признаков с резервными методами""" | |
| print("\n=== ЗАПУСК УЛУЧШЕННОГО ИЗВЛЕЧЕНИЯ ПРИЗНАКОВ ===") | |
| # Определяем колонку с транскриптами | |
| transcript_cols = [col for col in df.columns if 'транскрипт' in col.lower()] | |
| if not transcript_cols: | |
| print("❌ Не найдена колонка с транскриптами") | |
| return pd.DataFrame() | |
| transcript_col = transcript_cols[0] | |
| texts = df[transcript_col].fillna('') | |
| print(f"Обработка {len(texts)} транскриптов...") | |
| try: | |
| # Пробуем основной экстрактор | |
| print("🔄 Попытка использовать RussianFeatureExtractor...") | |
| extractor = RussianFeatureExtractor() | |
| features_df = extractor.extract_features_for_dataframe(df) | |
| if not features_df.empty: | |
| print("✅ RussianFeatureExtractor успешно отработал") | |
| return features_df | |
| else: | |
| print("❌ RussianFeatureExtractor вернул пустой DataFrame") | |
| except Exception as e: | |
| print(f"❌ Ошибка в RussianFeatureExtractor: {e}") | |
| print("🔄 Переход на резервный метод...") | |
| # Резервный метод - базовые признаки | |
| print("Использование резервного метода извлечения признаков...") | |
| features_df = test_alternative_features(texts) | |
| return features_df | |
| def analyze_correlations_with_scores(features_df, original_df): | |
| """Анализ корреляций с реальными оценками""" | |
| print("\n=== АНАЛИЗ КОРРЕЛЯЦИЙ ===") | |
| # Находим колонку с оценками | |
| score_cols = [col for col in original_df.columns if 'оценк' in col.lower() or 'балл' in col.lower()] | |
| if not score_cols: | |
| print("❌ Не найдены колонки с оценками") | |
| return | |
| score_col = score_cols[0] | |
| # Объединяем признаки с оценками | |
| analysis_df = features_df.copy() | |
| analysis_df['real_score'] = original_df[score_col].values | |
| # Удаляем строки с пропусками | |
| analysis_clean = analysis_df.dropna() | |
| if len(analysis_clean) < 2: | |
| print("❌ Недостаточно данных для анализа корреляций") | |
| return | |
| # Анализ корреляций | |
| correlations = analysis_clean.corr()['real_score'].sort_values(key=abs, ascending=False) | |
| print("\nТоп-15 наиболее коррелирующих признаков:") | |
| print("-" * 50) | |
| for feature, corr in correlations.items(): | |
| if feature != 'real_score': | |
| direction = "+" if corr > 0 else "-" | |
| significance = "***" if abs(corr) > 0.3 else "**" if abs(corr) > 0.2 else "*" if abs(corr) > 0.1 else "" | |
| print(f" {direction} {feature}: {corr:+.3f} {significance}") | |
| # Визуализация топ-признаков | |
| top_features = correlations.head(6).index.tolist() | |
| if 'real_score' in top_features: | |
| top_features.remove('real_score') | |
| if top_features: | |
| plt.figure(figsize=(12, 8)) | |
| for i, feature in enumerate(top_features[:5]): | |
| plt.subplot(2, 3, i + 1) | |
| plt.scatter(analysis_clean[feature], analysis_clean['real_score'], alpha=0.6) | |
| plt.xlabel(feature) | |
| plt.ylabel('Real Score') | |
| plt.title(f'r = {correlations[feature]:.3f}') | |
| plt.tight_layout() | |
| plt.show() | |
| return analysis_clean | |
| def save_detailed_report(features_df, original_df, analysis_df): | |
| """Сохранение детального отчета""" | |
| print("\n=== СОХРАНЕНИЕ ОТЧЕТА ===") | |
| # Сохраняем признаки | |
| features_df.to_csv('extracted_features_enhanced.csv', encoding='utf-8') | |
| print("✅ Признаки сохранены в extracted_features_enhanced.csv") | |
| # Детальный отчет | |
| with open('features_analysis_report.txt', 'w', encoding='utf-8') as f: | |
| f.write("ДЕТАЛЬНЫЙ ОТЧЕТ ПО АНАЛИЗУ ПРИЗНАКОВ\n") | |
| f.write("=" * 50 + "\n\n") | |
| f.write(f"ОБЩАЯ СТАТИСТИКА:\n") | |
| f.write(f"- Обработано строк: {len(features_df)}/{len(original_df)}\n") | |
| f.write(f"- Извлечено признаков: {len(features_df.columns)}\n") | |
| f.write(f"- Заполненность данных: {features_df.notna().mean().mean():.1%}\n\n") | |
| f.write("СПИСОК ПРИЗНАКОВ:\n") | |
| for col in features_df.columns: | |
| f.write(f"\n{col}:\n") | |
| f.write(f" Тип: {features_df[col].dtype}\n") | |
| f.write(f" Не-NULL: {features_df[col].notna().sum()}\n") | |
| f.write(f" Среднее: {features_df[col].mean():.3f}\n") | |
| f.write(f" Std: {features_df[col].std():.3f}\n") | |
| if analysis_df is not None and 'real_score' in analysis_df.columns: | |
| corr = analysis_df.corr()['real_score'].get(col, 0) | |
| f.write(f" Корреляция с оценкой: {corr:+.3f}\n") | |
| if analysis_df is not None: | |
| f.write("\nКОРРЕЛЯЦИОННЫЙ АНАЛИЗ:\n") | |
| correlations = analysis_df.corr()['real_score'].sort_values(key=abs, ascending=False) | |
| for feature, corr in correlations.items(): | |
| if feature != 'real_score' and abs(corr) > 0.1: | |
| f.write(f" {feature}: {corr:+.3f}\n") | |
| print("✅ Детальный отчет сохранен в features_analysis_report.txt") | |
| def main(): | |
| """Основная функция тестирования""" | |
| print("🚀 ЗАПУСК РАСШИРЕННОГО ТЕСТИРОВАНИЯ") | |
| print("=" * 60) | |
| # Проверка окружения | |
| check_environment() | |
| # Загрузка данных | |
| df = load_and_analyze_dataset() | |
| if df is None: | |
| print("❌ Не удалось загрузить данные для тестирования") | |
| return | |
| # Извлечение признаков | |
| features_df = enhanced_feature_extraction(df) | |
| if features_df.empty: | |
| print("❌ Не удалось извлечь признаки") | |
| return | |
| # Анализ корреляций | |
| analysis_df = analyze_correlations_with_scores(features_df, df) | |
| # Сохранение результатов | |
| save_detailed_report(features_df, df, analysis_df) | |
| print("\n" + "=" * 60) | |
| print("ТЕСТИРОВАНИЕ ЗАВЕРШЕНО!") | |
| print("=" * 60) | |
| if __name__ == "__main__": | |
| main() |