Professional Documents
Culture Documents
Data Mining
Data Mining
Task0
Json 파일 전처리
# Data 하위 폴더에 있는 json 파일 하나씩 search
base_path = './Data'
rows=[]
# Scene data
for scene in json_data['scene']['data']:
img_name = scene['img_name']
for occupant in scene['occupant']:
row = {
'img_name': img_name,
'occupant_id':
occupant.get('occupant_id', None),
'action': occupant.get('action', None),
'emotion': occupant.get('emotion',
None),
}
rows.append(row)
# Creating a DataFrame
combined_df = pd.DataFrame(rows)
# occupant df
occupant_df =
pd.DataFrame(json_data['occupant_info'])
# sensor df
sensor_df = pd.DataFrame()
avg_ppg = sum(sensor_data['PPG']) /
len(sensor_data['PPG'])
std_ppg = statistics.stdev(sensor_data['PPG'])
if len(sensor_data['PPG']) > 1 else 0
avg_spo2 = sum(sensor_data['SPO2']) /
len(sensor_data['SPO2'])
std_spo2 = statistics.stdev(sensor_data['SPO2'])
if len(sensor_data['SPO2']) > 1 else 0
sensor_df = pd.concat([sensor_df,
avg_std_sensor_df], ignore_index=True)
# Combine scene_df, sensor_df, occupant_df
combined_df = pd.merge(combined_df, sensor_df,
on='occupant_id')
combined_df = pd.merge(combined_df, occupant_df,
on='occupant_id')
combined_df =
combined_df.drop_duplicates(subset=columns_to_check).reset_i
ndex(drop=True)
all_combined_df = pd.concat([all_combined_df,
combined_df], ignore_index=True)
특정 폴더 안에 있는 JSON 파일들을 읽어, 그 데이터를 분석하고 처리하는
과정을 담고 있다. 구체적으로 살펴보면 아래의 단계와 같다.
1. 파일 탐색 및 읽기
2. JSON 데이터 처리
scene 의 sensor
부분에서 각 센서 데이터의 평균과 표준편차를
계산하여 sensor_df 에 추가한다.
3. 데이터 병합 및 중복 제거
4. 결합된 데이터의 최종 병합
각 JSON 파일로부터 생성된 combined_df 를 all_combined_df 에
추가한다. 이렇게 함으로써 모든 파일의 데이터가 하나의 큰
데이터프레임에 포함되도록 한다.
# 'occupant_age' 열의 각 값에 대해 매핑 함수 적용
all_df['occupant_age'] =
all_df['occupant_age'].apply(age_group_to_numeric)
# typo
all_df = all_df.rename(columns={'occupant_posoition ':
'occupant_position'})
# 'occupant_sex' 및 'occupant_position' 열을 원-핫 인코딩
sex_dummies = pd.get_dummies(all_df['occupant_sex'],
prefix='sex')
position_dummies =
pd.get_dummies(all_df['occupant_position'],
prefix='position')
# normalize
columns_to_normalize = ['ECG_avg', 'ECG_std', 'PPG_avg',
'PPG_std', 'SPO2_avg', 'EEG_avg', 'occupant_age']
all_df[columns_to_normalize] = (all_df[columns_to_normalize]
- all_df[columns_to_normalize].mean()) /
all_df[columns_to_normalize].std()
all_df.to_csv('all_data_norm.csv', index=False,
encoding='CP949')
추가적으로, 데이터 전처리 과정을 수행하여, JSON 파일에서 추출된
데이터를 분석에 적합한 형태로 변환한다. 주요 단계는 다음과 같다:
1. 결측치 제거
2. 연령 데이터 변환
함수는 'occupant_age' 열의 문자열 값을 숫자
age_group_to_numeric
3. 데이터 정제
수정한다.
4. 원-핫 인코딩
이를 원래 데이터프레임에 결합한다.
5. 불필요한 열 제거
6. 데이터 정규화
7. 데이터 저장:
############################################################
####################
### Task 1.
############################################################
########
############################################################
####################
# '분류 없음' 행 제거
data <- data %>% filter(emotion != '분류 없음')
head(data)
# factor 변환
data$emotion <- as.factor(data$emotion)
# label
labelDF <- data.frame(y = data$emotion, val=1, i =
1:nrow(data))
# 미사용하는 열 제거
dataX <- data[, -which(names(data) %in% c("img_name",
"emotion", "action", "occupant_id",
"occupant_sex",
"occupant_position"))]
# Prediction function
predict_emotion <- function(inputMat){
nData = data.frame(inputMat)
result <- sapply(modelList, function(x) {predict(x,
newdata = nData, type = 'response')})
return(apply(result, 1, function(x)
{emotion_levels[which.max(x)]})) # 가장 확률이 높은 class
# Calculate accuracy
train_accuracy <- mean(train_pred_emotions ==
train_emotions)
test_accuracy <- mean(test_pred_emotions == test_emotions)
# Compare
print(train_accuracy)
print(test_accuracy)
# under fitting
위 단계는 Multi class logistic regression 을 binary logistic regression 모델을
class 의 개수만큼 생성하여 직접 구현한다.
변수에 저장한다.
2. 데이터 전처리
제거한다.
3. 원-핫 인코딩 및 라벨 준비
열을 제거한다.
4. 데이터 정제
5. 로지스틱 회귀 모델 리스트 생성
6. 예측 함수 정의
7. 데이터 분할 및 모델 평가
데이터를 훈련 세트와 테스트 세트로 분할한다.
모델 성능 비교
Task2
feature engineering 을 진행하여 새로운 변수를 추가하거나 필요 없는
변수를 삭제하는 방법으로 모델을 최적화해보자. 변수 추가를 통한 최적화
과정 중 overfitting 이 일어난다면 regularization 을 통해서 과적합을
해소하여보고 성능의 변화를 확인해보자.
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler,
PolynomialFeatures
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score,
classification_report
# 데이터 불러오기
data = pd.read_csv('all_data.csv', encoding='cp949')
# '분류없음' 행 제거
data = data[data['emotion'] != '분류없음']
# 원-핫 인코딩 적용
emotion_one_hot = pd.get_dummies(data['emotion'])
data = pd.concat([data, emotion_one_hot], axis=1)
# 상호작용 및 다항 특성 생성
polynomial_features = PolynomialFeatures(degree=2,
include_bias=False, interaction_only=False)
sensor_data = data[['ECG_avg', 'ECG_std', 'PPG_avg',
'PPG_std', 'SPO2_avg', 'EEG_avg']]
sensor_poly = polynomial_features.fit_transform(sensor_data)
sensor_poly_df = pd.DataFrame(sensor_poly,
columns=polynomial_features.get_feature_names_out(sensor_dat
a.columns))
data = pd.concat([data, sensor_poly_df], axis=1)
# 필요한 특성 선택
features = list(sensor_poly_df.columns) + ['occupant_age',
'position_back', 'position_front']
X = data[features]
# 타겟 변수 선택
y = data[emotion_one_hot.columns]
# 데이터 분할 및 랜덤 시드 설정
np.random.seed(123)
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2, random_state=123)
# 특성 표준화
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 모델 구축 및 예측
models = {}
emotions = y.columns
for emotion in emotions:
model = LogisticRegression(solver='lbfgs',
max_iter=1000, random_state=123)
model.fit(X_train_scaled, y_train[emotion])
models[emotion] = model
# 멀티클래스 예측 함수 정의
def predict_multiclass(X_scaled):
probabilities = np.array([model.predict_proba(X_scaled)
[:,1] for emotion, model in models.items()]).T
predicted_class_indices = np.argmax(probabilities,
axis=1)
predicted_classes = [emotions[idx] for idx in
predicted_class_indices]
return predicted_classes
# 훈련 및 테스트 데이터에 대한 예측
y_train_pred = predict_multiclass(X_train_scaled)
y_test_pred = predict_multiclass(X_test_scaled)
# 성능 평가
train_accuracy = accuracy_score(y_train_original,
y_train_pred)
test_accuracy = accuracy_score(y_test_original, y_test_pred)
1. 다항 특성 생성:
2. 데이터프레임 변환:
특성 선택
1. 특성 리스트 구성:
2. 최종 특성 데이터셋 구축:
# 데이터 불러오기
data = pd.read_csv('all_data.csv', encoding='cp949')
# '분류없음' 행 제거
data = data[data['emotion'] != '분류없음']
# 원-핫 인코딩 적용
emotion_one_hot = pd.get_dummies(data['emotion'])
data = pd.concat([data, emotion_one_hot], axis=1)
# 상호작용 및 다항 특성 생성
polynomial_features = PolynomialFeatures(degree=2,
include_bias=False, interaction_only=False)
sensor_data = data[['ECG_avg', 'PPG_avg', 'EEG_avg']]
sensor_poly = polynomial_features.fit_transform(sensor_data)
sensor_poly_df = pd.DataFrame(sensor_poly,
columns=polynomial_features.get_feature_names_out(sensor_dat
a.columns))
data = pd.concat([data, sensor_poly_df], axis=1)
# 필요한 특성 선택
X = data.drop(['emotion', 'img_name', 'occupant_id',
'occupant_sex', 'occupant_position'] +
list(emotion_one_hot.columns), axis=1)
# 타겟 변수 선택
y = data[emotion_one_hot.columns]
# 데이터 분할 및 랜덤 시드 설정
np.random.seed(123)
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.2, random_state=123)
# 특성 표준화
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 특성 선택
selector = SelectKBest(f_classif, k=20)
X_train_scaled = selector.fit_transform(X_train_scaled,
y_train.idxmax(axis=1))
X_test_scaled = selector.transform(X_test_scaled)
# 감정 클래스별로 모델 구축
models = {}
emotions = y.columns
for emotion in emotions:
model = LogisticRegression(solver='lbfgs',
max_iter=1000, random_state=123)
model.fit(X_train_scaled, y_train[emotion])
models[emotion] = model
# 멀티클래스 예측 함수
def predict_multiclass(X_scaled):
probabilities = np.array([model.predict_proba(X_scaled)
[:,1] for emotion, model in models.items()]).T
predicted_class_indices = np.argmax(probabilities,
axis=1)
predicted_classes = [emotions[idx] for idx in
predicted_class_indices]
return predicted_classes
# 훈련 및 테스트 데이터에 대한 예측
y_train_pred = predict_multiclass(X_train_scaled)
y_test_pred = predict_multiclass(X_test_scaled)
# 원본 'emotion' 타겟과 비교
y_train_original = y_train.idxmax(axis=1)
y_test_original = y_test.idxmax(axis=1)
# 성능 평가
train_accuracy = accuracy_score(y_train_original,
y_train_pred)
test_accuracy = accuracy_score(y_test_original, y_test_pred)
print("Train Accuracy:", train_accuracy)
print("Test Accuracy:", test_accuracy)
추가된 부분 :
1. 이상치 처리:
2. 상호작용 및 다항 특성 생성:
3. 특성 선택:
SelectKBest 와 f_classif 를
사용하여 모델에 가장 유의미한 영향을
미치는 상위 20 개의 특성을 선택한다. 이는 모델의 복잡도를
관리하고, 중요한 정보에 집중하게 함으로써 성능을 향상시킬
수 있다.
성능 평가결과 2
1. 데이터 처리의 미흡
2. 하이퍼파라미터 설정
3. 클래스 불균형
결론
Feature Engineering 을 통해 다항 및 상호작용 특성을 추가했음에도
불구하고 성능이 저조해진 결과는 여러 요인에 기인할 수 있다. 데이터
처리의 미흡, 하이퍼파라미터 설정의 부적절함, 그리고 클래스 불균형을
의심해 볼 수 있는데, 향후 성능 개선을 위해서는 아래와 같은 접근을 통해
모델의 성능을 개선을 시도해 볼 수 있다.