exam-evaluator / test_features.py
KarmanovaLidiia
Initial clean commit for HF Space (models via Git LFS)
bcb314a
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()