출처는 chatGPT
문제: 고객 연령대 분석 및 구매 패턴 예측
한 온라인 쇼핑몰에서 고객의 연령과 구매 금액을 분석하여 특정 연령대의 구매 패턴을 예측하려고 합니다. 고객 데이터를 분석하고, quantile을 이용해 연령별 특징을 파악한 후, 구매 가능성을 예측하는 간단한 모델을 구축하세요.
주어진 데이터 (샘플)
import pandas as pd
import numpy as np
np.random.seed(42)
data = pd.DataFrame({
'customer_id': range(1, 101),
'age': np.random.randint(18, 70, 100),
'purchase_amount': np.random.randint(10, 1000, 100)
})
서브 문제 1: 연령대별 분위수(Quantile) 분석
주어진 고객 데이터에서 age(연령) 값을 기준으로 4분위수(0%, 25%, 50%, 75%, 100%)를 구하고, 해당 분위수를 기준으로 연령대를 다음과 같이 분류하세요.
- 젊은층 (Q1 이하)
- 중간층 (Q1 ~ Q3)
- 고령층 (Q3 초과)
각 연령대별 평균 구매 금액을 구하세요.
서브 문제 2: 특정 연령대 구매 예측
특정 연령대(예: Q2 ~ Q3)의 고객이 고액 구매(예: 구매 금액이 전체 데이터의 75% 분위수 이상)를 할 확률을 계산하세요.
힌트:
- purchase_amount의 75% 분위수를 구한 후, 해당 값을 기준으로 고액 구매 여부를 정의하세요.
- 특정 연령대(Q2 ~ Q3)의 고객들 중 고액 구매자의 비율을 구하세요.
추가 문제: 간단한 구매 예측 모델 구축
위의 분석을 바탕으로, 나이(age)를 기반으로 구매 금액(purchase_amount)을 예측하는 선형 회귀 모델을 scikit-learn을 이용해 학습하고 평가하세요.
- 데이터를 훈련 세트(80%)와 테스트 세트(20%)로 분리하세요.
- LinearRegression을 사용하여 모델을 학습하세요.
- 모델의 성능을 평가하세요 (예: MSE, R² 스코어 등).
#1. 답
pandas와 numpy를 활용하여 데이터 분석을 수행하고, scikit-learn을 이용해 간단한 선형 회귀 모델을 구축합니다.
1. 데이터 생성
먼저, 샘플 데이터를 생성합니다.
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# 랜덤 시드 설정
np.random.seed(42)
# 데이터 생성
data = pd.DataFrame({
'customer_id': range(1, 101),
'age': np.random.randint(18, 70, 100),
'purchase_amount': np.random.randint(10, 1000, 100)
})
print(data.head()) # 데이터 샘플 출력
2. 연령대별 분위수(Quantile) 분석
연령을 4분위수로 나누고, 각 연령대별 평균 구매 금액을 계산합니다.
# 분위수 계산
q1, q2, q3 = data['age'].quantile([0.25, 0.5, 0.75])
# 연령대 구분
def categorize_age(age):
if age <= q1:
return '젊은층'
elif age <= q3:
return '중간층'
else:
return '고령층'
data['age_group'] = data['age'].apply(categorize_age)
# 연령대별 평균 구매 금액 계산
age_group_avg_purchase = data.groupby('age_group')['purchase_amount'].mean()
print(age_group_avg_purchase)
3. 특정 연령대(Q2 ~ Q3)의 고객이 고액 구매를 할 확률 계산
고액 구매 기준을 75% 분위수로 설정하고, 특정 연령대(Q2 ~ Q3)의 고객 중 고액 구매자의 비율을 구합니다.
# 고액 구매 기준 (75% 분위수 이상)
high_purchase_threshold = data['purchase_amount'].quantile(0.75)
# 고액 구매 여부 컬럼 추가
data['high_purchaser'] = data['purchase_amount'] >= high_purchase_threshold
# Q2 ~ Q3에 해당하는 고객 추출
mid_age_group = data[(data['age'] > q1) & (data['age'] <= q3)]
# 중간층에서 고액 구매자의 비율
high_purchase_ratio = mid_age_group['high_purchaser'].mean()
print(f"Q2 ~ Q3 연령대의 고객이 고액 구매를 할 확률: {high_purchase_ratio:.2%}")
4. 연령을 기반으로 구매 금액을 예측하는 선형 회귀 모델 구축
선형 회귀 모델을 학습하고 평가합니다.
# 입력(X)과 출력(y) 설정
X = data[['age']]
y = data['purchase_amount']
# 데이터 분할 (훈련 80%, 테스트 20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 선형 회귀 모델 생성 및 학습
model = LinearRegression()
model.fit(X_train, y_train)
# 예측
y_pred = model.predict(X_test)
# 모델 평가
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"모델 평가 - MSE: {mse:.2f}, R²: {r2:.2f}")
결과 요약
- 연령을 4분위수로 구분하여 각 연령대별 평균 구매 금액을 확인
- Q2 ~ Q3 연령대의 고객이 고액 구매를 할 확률을 계산
- 나이를 기반으로 구매 금액을 예측하는 선형 회귀 모델을 구축 및 평가
#2. 다음은 조건부 확률을 활용한 데이터 분석 문제입니다.
수치형 데이터를 범주형으로 변환하는 과정과 정규표현식 활용도 포함하였습니다.
문제: 고객 리뷰 분석 및 긍정적 리뷰 예측
한 온라인 쇼핑몰에서 고객 리뷰 데이터를 분석하고, 특정 조건에서 긍정적인 리뷰가 나올 확률을 계산한 후, 이를 예측하는 간단한 모델을 구축하세요.
주어진 데이터 (샘플)
import pandas as pd
import numpy as np
np.random.seed(42)
data = pd.DataFrame({
'customer_id': range(1, 101),
'review_length': np.random.randint(20, 500, 100), # 리뷰 길이 (단어 수)
'rating': np.random.randint(1, 6, 100), # 1~5점 사이의 별점
'review_text': np.random.choice(['좋아요!', '별로에요.', '최고예요!', '별로 추천 안해요.', '정말 만족해요!'], 100) # 랜덤 리뷰
})
서브 문제 1: 리뷰 길이를 기반으로 범주화
리뷰 길이(review_length)를 **4분위수(quantile)**를 기준으로 범주형으로 변환하세요.
- 짧은 리뷰 (Q1 이하)
- 보통 리뷰 (Q1 ~ Q3)
- 긴 리뷰 (Q3 초과)
각 리뷰 길이 범주별 평균 평점을 계산하세요.
1-1. 100과 300을 기준으로 세 구간으로 변환
서브 문제 2: 긍정적 리뷰일 확률 계산 (조건부 확률)
긍정적 리뷰를 별점 4점 이상으로 정의하고,
주어진 리뷰 길이 범주별로 긍정적 리뷰가 나올 확률을 계산하세요.
힌트:
- rating이 4점 이상인 경우 긍정적 리뷰로 분류
- 각 리뷰 길이 범주에서 긍정적 리뷰의 비율을 구하세요
추가 문제: 리뷰 텍스트에서 긍정 단어 포함 여부 분석 (정규표현식 활용)
주어진 review_text에서 "좋아요|최고|만족" 등의 단어가 포함된 경우 긍정적인 리뷰로 간주하세요.
각 리뷰 길이 범주에서 긍정 단어 포함 비율을 계산하세요.
추가 문제: 리뷰 길이를 기반으로 별점을 예측하는 회귀 모델 구축
리뷰 길이를 기반으로 rating을 예측하는 선형 회귀 모델을 scikit-learn을 이용해 학습하고 평가하세요.
- 데이터를 훈련 세트(80%)와 테스트 세트(20%)로 분리하세요.
- LinearRegression을 사용하여 모델을 학습하세요.
- 모델의 성능을 평가하세요 (예: MSE, R² 스코어 등).
#2. 답
1. 데이터 생성
import pandas as pd
import numpy as np
import re
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# 랜덤 시드 설정
np.random.seed(42)
# 데이터 생성
data = pd.DataFrame({
'customer_id': range(1, 101),
'review_length': np.random.randint(20, 500, 100), # 리뷰 길이 (단어 수)
'rating': np.random.randint(1, 6, 100), # 별점 (1~5점)
'review_text': np.random.choice(
['좋아요!', '별로에요.', '최고예요!', '별로 추천 안해요.', '정말 만족해요!'], 100) # 랜덤 리뷰
})
print(data.head()) # 데이터 샘플 출력
2. 리뷰 길이를 범주화 (Quantile 활용/ 특정 값 기준)
# 분위수 계산
q1, q2, q3 = data['review_length'].quantile([0.25, 0.5, 0.75])
# 리뷰 길이를 범주화하는 함수
def categorize_review_length(length):
if length <= q1:
return '짧은 리뷰'
elif length <= q3:
return '보통 리뷰'
else:
return '긴 리뷰'
data['review_category'] = data['review_length'].apply(categorize_review_length)
# 리뷰 길이 범주별 평균 별점 계산
review_group_avg_rating = data.groupby('review_category')['rating'].mean()
print(review_group_avg_rating)
2-1.
리뷰 길이를 범주형으로 변환하는 기준을 Quantile 대신 특정 값 기준(1, 3)으로 구분하도록 수정하였습니다.
아래는 변경된 코드입니다.
1. 리뷰 길이를 특정 값 기준으로 범주화
# 특정 값 기준으로 리뷰 길이 범주화
def categorize_review_length(length):
if length < 100: # 100 미만이면 짧은 리뷰
return '짧은 리뷰'
elif length < 300: # 100 이상 300 미만이면 보통 리뷰
return '보통 리뷰'
else: # 300 이상이면 긴 리뷰
return '긴 리뷰'
data['review_category'] = data['review_length'].apply(categorize_review_length)
# 리뷰 길이 범주별 평균 별점 계산
review_group_avg_rating = data.groupby('review_category')['rating'].mean()
print(review_group_avg_rating)
이제 리뷰 길이를 100과 300을 기준으로 세 구간으로 나누었습니다.
나머지 로직(조건부 확률 계산, 정규표현식 분석, 회귀 모델)은 그대로 유지됩니다. 😊
3. 리뷰 길이별 긍정적 리뷰 비율 계산 (조건부 확률)
# 긍정적 리뷰 (4점 이상)
data['positive_review'] = data['rating'] >= 4
# 각 리뷰 길이 범주에서 긍정적 리뷰 비율 계산
positive_review_ratio = data.groupby('review_category')['positive_review'].mean()
print("리뷰 길이별 긍정적 리뷰 비율:")
print(positive_review_ratio)
4. 정규표현식을 이용한 긍정 단어 포함 여부 분석
# 정규표현식을 이용한 긍정 단어 포함 여부 확인
positive_words = re.compile(r'좋아요|최고|만족')
# 리뷰에 긍정 단어 포함 여부 (True/False)
data['contains_positive_word'] = data['review_text'].apply(lambda x: bool(positive_words.search(x)))
# 각 리뷰 길이 범주에서 긍정 단어 포함 비율 계산
positive_word_ratio = data.groupby('review_category')['contains_positive_word'].mean()
print("리뷰 길이별 긍정 단어 포함 비율:")
print(positive_word_ratio)
5. 리뷰 길이를 기반으로 별점 예측 (선형 회귀 모델)
# 입력(X)과 출력(y) 설정
X = data[['review_length']]
y = data['rating']
# 데이터 분할 (훈련 80%, 테스트 20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 선형 회귀 모델 생성 및 학습
model = LinearRegression()
model.fit(X_train, y_train)
# 예측
y_pred = model.predict(X_test)
# 모델 평가
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"모델 평가 - MSE: {mse:.2f}, R²: {r2:.2f}")
결과 요약
- 리뷰 길이를 Quantile을 이용해 범주화하고, 각 범주별 평균 별점을 계산
- 각 리뷰 길이 범주에서 긍정적 리뷰(4점 이상) 확률을 조건부 확률로 계산
- 리뷰 텍스트에서 정규표현식을 활용하여 긍정 단어 포함 여부를 분석
- 리뷰 길이를 기반으로 별점을 예측하는 선형 회귀 모델을 학습하고 평가
문제: 온라인 쇼핑몰 고객의 재구매율 분석
한 온라인 쇼핑몰에서 고객의 **재구매 여부(repurchase)**를 분석하고, 특정 조건에서 재구매할 확률을 계산한 후, 이를 예측하는 간단한 모델을 구축하세요.
주어진 데이터 (샘플)
고객의 총 구매 횟수, 평균 구매 금액, 구매한 상품 리뷰 내용이 주어집니다.
이를 바탕으로 조건부 확률을 이용하여 재구매 확률을 계산하세요.
import pandas as pd
import numpy as np
np.random.seed(42)
data = pd.DataFrame({
'customer_id': range(1, 101),
'total_purchases': np.random.randint(1, 10, 100), # 총 구매 횟수
'avg_spending': np.random.randint(10, 500, 100), # 평균 구매 금액 ($)
'review_text': np.random.choice(['좋아요!', '별로예요.', '최고예요!', '다시는 안 살래요.', '정말 만족해요!'], 100), # 리뷰 텍스트
'repurchase': np.random.choice([0, 1], 100, p=[0.6, 0.4]) # 재구매 여부 (0: 없음, 1: 있음)
})
print(data.head()) # 데이터 샘플 출력
서브 문제 1: 구매 횟수를 기반으로 범주화
고객의 **총 구매 횟수(total_purchases)**를 기준으로 범주형으로 변환하세요.
- 초보 고객: 1~3회 구매
- 일반 고객: 4~6회 구매
- 충성 고객: 7회 이상 구매
각 **고객 유형별 재구매율(조건부 확률)**을 계산하세요.
서브 문제 2: 긍정적 리뷰 작성 고객의 재구매 확률 계산 (조건부 확률)
리뷰 내용(review_text)에서 "좋아요|최고|만족" 등의 긍정적인 단어가 포함된 경우,
이 고객이 재구매할 확률을 조건부 확률로 계산하세요.
힌트:
- 정규표현식(re)을 사용하여 특정 단어 포함 여부를 판별
- 긍정적인 리뷰를 남긴 고객 중 재구매한 비율을 계산
추가 문제: 평균 구매 금액을 이용한 회귀 모델 구축
고객의 **평균 구매 금액(avg_spending)**을 사용하여 재구매 여부를 예측하는 로지스틱 회귀 모델을 구축하세요.
- 데이터를 **훈련 세트(80%)와 테스트 세트(20%)**로 분리하세요.
- LogisticRegression을 사용하여 모델을 학습하세요.
- 모델의 성능을 평가하세요 (예: 정확도, 정밀도, 재현율 등).
#3. 답
조건부 확률 계산, 정규표현식 활용, 범주화, 그리고 로지스틱 회귀 모델을 포함했습니다.
1. 데이터 생성
import pandas as pd
import numpy as np
import re
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report
# 랜덤 시드 설정
np.random.seed(42)
# 데이터 생성
data = pd.DataFrame({
'customer_id': range(1, 101),
'total_purchases': np.random.randint(1, 10, 100), # 총 구매 횟수
'avg_spending': np.random.randint(10, 500, 100), # 평균 구매 금액 ($)
'review_text': np.random.choice(['좋아요!', '별로예요.', '최고예요!', '다시는 안 살래요.', '정말 만족해요!'], 100), # 리뷰 텍스트
'repurchase': np.random.choice([0, 1], 100, p=[0.6, 0.4]) # 재구매 여부 (0: 없음, 1: 있음)
})
print(data.head()) # 데이터 샘플 출력
2. 구매 횟수를 범주형으로 변환
# 구매 횟수를 범주형 변수로 변환
def categorize_purchases(purchases):
if purchases <= 3:
return '초보 고객'
elif purchases <= 6:
return '일반 고객'
else:
return '충성 고객'
data['customer_type'] = data['total_purchases'].apply(categorize_purchases)
# 각 고객 유형별 재구매 확률 계산 (조건부 확률)
repurchase_rate = data.groupby('customer_type')['repurchase'].mean()
print("고객 유형별 재구매 확률:")
print(repurchase_rate)
3. 정규표현식으로 긍정적 리뷰 포함 여부 확인 & 조건부 확률 계산
# 정규표현식을 이용한 긍정 단어 포함 여부 확인
positive_words = re.compile(r'좋아요|최고|만족')
# 긍정적인 단어가 포함된 리뷰 여부
data['contains_positive_word'] = data['review_text'].apply(lambda x: bool(positive_words.search(x)))
# 긍정적 리뷰를 남긴 고객의 재구매 확률 계산
positive_review_repurchase_rate = data.groupby('contains_positive_word')['repurchase'].mean()
print("긍정적 리뷰 포함 여부에 따른 재구매 확률:")
print(positive_review_repurchase_rate)
4. 로지스틱 회귀 모델을 이용한 재구매 예측
# 입력(X)과 출력(y) 설정
X = data[['avg_spending']] # 평균 구매 금액만 사용
y = data['repurchase'] # 재구매 여부
# 데이터 분할 (훈련 80%, 테스트 20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 로지스틱 회귀 모델 생성 및 학습
model = LogisticRegression()
model.fit(X_train, y_train)
# 예측
y_pred = model.predict(X_test)
# 모델 평가
accuracy = accuracy_score(y_test, y_pred)
report = classification_report(y_test, y_pred)
print(f"모델 정확도: {accuracy:.2f}")
print("분류 보고서:")
print(report)
결과 요약
- 고객의 구매 횟수를 범주형(초보 고객, 일반 고객, 충성 고객)으로 변환하고,
- 각 유형별 **재구매 확률(조건부 확률)**을 계산
- 리뷰 내용에서 **정규표현식(Regex)**을 사용하여 긍정적인 단어 포함 여부를 확인하고,
- 긍정적 리뷰를 남긴 고객의 **재구매 확률(조건부 확률)**을 계산
- 로지스틱 회귀 모델을 사용하여
- 평균 구매 금액을 기반으로 재구매 여부를 예측하고, 성능을 평가
이제 코드를 실행해보면서 결과를 분석해 보세요! 😊
추가로 궁금한 점이 있으면 질문 주세요.
문제: 온라인 학습 플랫폼에서 학생들의 학습 성과 분석 및 예측
온라인 학습 플랫폼에서 학생들의 학습 시간, 과제 제출 여부, 시험 점수 등의 데이터를 분석하여,
학생이 과정을 성공적으로 수료할 가능성을 예측하는 문제입니다.
📌 메인 문제: "학생의 학습 데이터를 분석하여 과정 수료 여부를 예측하세요."
학생의 학습 패턴과 성적을 바탕으로 어떤 학생이 과정을 성공적으로 수료할 가능성이 높은지 예측하는 것이 목표입니다.
이를 위해 이상치 탐지, 데이터 전처리, 정규표현식 활용, 조건부 확률 계산, 교차표 분석(crosstab) 등을 수행합니다.
🔹 서브 문제 1: 학습 시간(수치형 데이터)을 기반으로 이상치 탐지 및 제거
- 학생들의 **주간 평균 학습 시간(weekly_study_hours)**을 분석합니다.
- 평균 + 1.5 표준편차를 초과하는 학습 시간은 이상치로 간주하고 제거합니다.
🔹 서브 문제 2: 과제 제출 상태를 분석하고 텍스트 데이터 전처리
- assignment_status 열에서 "제출 완료", "지각 제출", "미제출" 등의 값을 정리하여,
**"제출" 또는 "미제출"**로 범주화합니다. - 정규표현식(Regex)을 이용해 "지각 제출"을 "미제출"로 변경합니다.
🔹 서브 문제 3: 학습 시간과 시험 점수를 기반으로 과정 수료율 분석 (조건부 확률 + 교차표 crosstab 활용)
- 학생들의 학습 시간을 3분위(Quantile) 기준으로 그룹화합니다.
- 낮음 (Low): Q1 이하
- 보통 (Medium): Q1 ~ Q3 사이
- 높음 (High): Q3 이상
- 각 그룹별 시험 점수 평균과 과정 수료 여부(course_completed) 간의 조건부 확률을 계산합니다.
- pd.crosstab()을 사용하여 학습 시간과 시험 점수의 관계를 분석합니다.
📌 Python 코드로 해결하기
import pandas as pd
import numpy as np
import re
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report
# 데이터 생성
np.random.seed(42)
data = pd.DataFrame({
'student_id': range(1, 101),
'weekly_study_hours': np.random.randint(1, 30, 100), # 주간 평균 학습 시간
'exam_score': np.random.randint(40, 100, 100), # 시험 점수
'assignment_status': np.random.choice(['제출 완료', '지각 제출', '미제출'], 100), # 과제 제출 상태
'course_completed': np.random.choice([0, 1], 100, p=[0.4, 0.6]) # 과정 수료 여부 (0: 미수료, 1: 수료)
})
print(data.head()) # 데이터 샘플 출력
🔹 서브 문제 1: 이상치 탐지 및 제거
# 이상치 기준: 평균 + 1.5 표준편차 초과
mean_hours = data['weekly_study_hours'].mean()
std_hours = data['weekly_study_hours'].std()
outlier_threshold = mean_hours + 1.5 * std_hours
# 이상치 제거
data = data[data['weekly_study_hours'] <= outlier_threshold]
print(f"이상치 제거 후 남은 데이터 개수: {len(data)}")
🔹 서브 문제 2: 정규표현식을 이용한 과제 제출 상태 정리
# 정규표현식을 이용하여 "지각 제출"을 "미제출"로 변경
data['assignment_status'] = data['assignment_status'].apply(lambda x: re.sub('지각 제출', '미제출', x))
# "제출 완료"와 "미제출" 두 개의 범주로 정리
data['assignment_status'] = data['assignment_status'].apply(lambda x: '제출' if x == '제출 완료' else '미제출')
print(data['assignment_status'].value_counts())
🔹 서브 문제 3: 학습 시간과 시험 점수를 기반으로 과정 수료율 분석
# 학습 시간 기준으로 그룹화 (Quantile 활용)
data['study_time_category'] = pd.qcut(data['weekly_study_hours'], q=3, labels=['낮음', '보통', '높음'])
# 학습 시간 그룹별 과정 수료율 계산 (조건부 확률)
completion_rate = data.groupby('study_time_category')['course_completed'].mean()
print("학습 시간 그룹별 과정 수료율:")
print(completion_rate)
# 학습 시간과 시험 점수의 관계 분석 (crosstab)
study_exam_crosstab = pd.crosstab(data['study_time_category'], data['exam_score'], normalize='index')
print("학습 시간과 시험 점수 간의 관계:")
print(study_exam_crosstab)
🔹 과정 수료 여부를 예측하는 로지스틱 회귀 모델 학습
# 입력(X)과 출력(y) 설정
X = data[['weekly_study_hours', 'exam_score']] # 학습 시간과 시험 점수만 사용
y = data['course_completed'] # 과정 수료 여부
# 데이터 분할 (훈련 80%, 테스트 20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 로지스틱 회귀 모델 생성 및 학습
model = LogisticRegression()
model.fit(X_train, y_train)
# 예측
y_pred = model.predict(X_test)
# 모델 평가
accuracy = accuracy_score(y_test, y_pred)
report = classification_report(y_test, y_pred)
print(f"모델 정확도: {accuracy:.2f}")
print("분류 보고서:")
print(report)
📌 결과 요약
- 학생들의 주간 학습 시간을 분석하고 이상치를 제거하여 데이터의 신뢰성을 높였습니다.
- **정규표현식(Regex)**을 사용하여 과제 제출 상태를 "제출"과 "미제출" 두 개의 범주로 정리하였습니다.
- 학습 시간(Quantile 기반 분류)과 과정 수료 여부의 관계를 분석하여,
- 학습 시간이 많을수록 과정 수료율이 증가하는지 확인하였습니다.
- 학습 시간과 시험 점수 데이터를 사용하여 로지스틱 회귀 모델을 학습하고,
- 학생의 과정 수료 여부를 예측하는 모델을 만들었습니다.
📌 문제: 의료 데이터 분석을 통한 환자 상태 예측
한 병원에서 환자의 건강 데이터를 분석하여 질병 여부를 예측하는 문제입니다.
환자의 건강 상태를 평가하고, 위험군을 분류하세요.
📌 메인 문제
환자의 연령, BMI(체질량지수), 혈압, 생활 습관(흡연 여부, 운동 빈도), 혈당 수치 등의 데이터를 이용하여
질병(당뇨병 또는 고혈압) 발생 여부를 분석하고 예측하세요.
import pandas as pd
import numpy as np
import re
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report
# 데이터 생성
np.random.seed(42)
data = pd.DataFrame({
'patient_id': range(1, 101),
'age': np.random.randint(20, 80, 100), # 연령
'BMI': np.random.normal(25, 5, 100), # 체질량지수 (정규분포)
'blood_pressure': np.random.randint(90, 180, 100), # 혈압
'glucose_level': np.random.randint(70, 150, 100), # 혈당 수치
'smoking_status': np.random.choice(['흡연', '비흡연', '가끔 흡연'], 100), # 흡연 여부
'activity_level': np.random.choice(['주 3~4회 운동', '매일 운동', '거의 안 함'], 100), # 운동 빈도
'has_disease': np.random.choice([0, 1], 100, p=[0.7, 0.3]) # 질병 발생 여부 (0: 건강, 1: 질병 위험군)
})
print(data.head()) # 데이터 샘플 출력
🔹 서브 문제 1
BMI와 혈압 수치의 이상치를 탐지하여 제거하세요.
🔹 서브 문제 2
흡연 상태와 운동 빈도를 정리하여 일관된 형식으로 변환하세요.
🔹 서브 문제 3
혈당 수치를 기준으로 범주화하여 위험군을 분류하고,
흡연 여부와 질병 발생 간의 관계를 분석하세요.
# 답
📌 메인 문제: "환자의 건강 데이터를 분석하여 질병 발생 여부를 예측하세요."
환자의 연령, BMI(체질량지수), 혈압, 생활 습관(흡연 여부, 운동 빈도), 혈당 수치 등을 분석하여
질병(당뇨병 또는 고혈압) 여부를 예측하는 것이 목표입니다.
이를 위해 이상치 탐지, 데이터 전처리, 정규표현식 활용, 가변수 변환, 그룹화 분석 등을 수행합니다.
🔹 서브 문제 1: 이상치 탐지 및 제거
- BMI(체질량지수)와 혈압(blood_pressure) 값의 이상치를 탐지하고 제거합니다.
- 평균 ± 2표준편차를 초과하는 값을 이상치로 간주하여 필터링합니다.
🔹 서브 문제 2: 흡연 여부 및 건강 습관 데이터 정리 (정규표현식 활용)
- smoking_status 열에서 "흡연", "비흡연", "가끔 흡연" 등의 값을 정리하여,
**"흡연자" 또는 "비흡연자"**로 범주화합니다. - 정규표현식(Regex)을 이용해 운동 빈도(activity_level) 값을 표준화합니다.
- "주 3~4회 운동" → "중간"
- "매일 운동" → "높음"
- "거의 안 함" → "낮음"
🔹 서브 문제 3: 혈당 수치를 기준으로 질병 발생 위험군 분석 (가변수 변환 + crosstab 활용)
- 혈당 수치(glucose_level)를 범주형 변수로 변환하여 위험군을 설정합니다.
- 정상 (Normal): 70 ~ 99
- 경계 (Pre-Diabetic): 100 ~ 125
- 위험 (Diabetic): 126 이상
- pd.crosstab()을 사용하여 흡연 여부와 질병 발생(당뇨병) 여부 간의 관계를 분석합니다.
🔹 서브 문제 1: BMI 및 혈압 이상치 탐지 및 제거
# 이상치 기준: 평균 ± 2표준편차 초과
bmi_mean, bmi_std = data['BMI'].mean(), data['BMI'].std()
bp_mean, bp_std = data['blood_pressure'].mean(), data['blood_pressure'].std()
bmi_threshold_low, bmi_threshold_high = bmi_mean - 2 * bmi_std, bmi_mean + 2 * bmi_std
bp_threshold_low, bp_threshold_high = bp_mean - 2 * bp_std, bp_mean + 2 * bp_std
# 이상치 제거
data = data[(data['BMI'] >= bmi_threshold_low) & (data['BMI'] <= bmi_threshold_high)]
data = data[(data['blood_pressure'] >= bp_threshold_low) & (data['blood_pressure'] <= bp_threshold_high)]
print(f"이상치 제거 후 데이터 개수: {len(data)}")
🔹 서브 문제 2: 흡연 여부 및 건강 습관 데이터 정리 (정규표현식 활용)
# "가끔 흡연"을 "흡연"으로 정리
data['smoking_status'] = data['smoking_status'].apply(lambda x: re.sub('가끔 흡연', '흡연', x))
# 운동 빈도 표준화
data['activity_level'] = data['activity_level'].apply(lambda x:
'높음' if '매일' in x else '중간' if '3~4회' in x else '낮음')
print(data[['smoking_status', 'activity_level']].value_counts())
🔹 서브 문제 3: 혈당 수치를 기준으로 질병 발생 위험군 분석 (가변수 변환 + crosstab 활용)
# 혈당 수치를 3단계로 범주화
def categorize_glucose(glucose):
if glucose < 100:
return '정상'
elif 100 <= glucose < 126:
return '경계'
else:
return '위험'
data['glucose_category'] = data['glucose_level'].apply(categorize_glucose)
# Crosstab을 사용한 흡연 여부와 질병 발생 여부 분석
smoking_disease_crosstab = pd.crosstab(data['smoking_status'], data['has_disease'], normalize='index')
print("흡연 여부와 질병 발생 간의 관계 (교차표):")
print(smoking_disease_crosstab)
🔹 질병 발생 여부를 예측하는 로지스틱 회귀 모델 학습
# 예측 변수 선택
X = data[['age', 'BMI', 'blood_pressure', 'glucose_level']] # 주요 변수
y = data['has_disease'] # 질병 발생 여부
# 데이터 분할 (훈련 80%, 테스트 20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 로지스틱 회귀 모델 생성 및 학습
model = LogisticRegression()
model.fit(X_train, y_train)
# 예측
y_pred = model.predict(X_test)
# 모델 평가
accuracy = accuracy_score(y_test, y_pred)
report = classification_report(y_test, y_pred)
print(f"모델 정확도: {accuracy:.2f}")
print("분류 보고서:")
print(report)
📌 결과 요약
- BMI 및 혈압 이상치를 제거하여 데이터의 신뢰도를 높였습니다.
- **정규표현식(Regex)**을 활용하여 흡연 여부를 통합하고, 운동 빈도를 표준화하였습니다.
- 혈당 수치를 기준으로 위험군을 분류하고, 질병 발생 가능성을 분석하였습니다.
- 흡연 여부와 질병 발생의 관계를 crosstab을 통해 시각화하였습니다.
- 질병 여부를 예측하는 로지스틱 회귀 모델을 학습하여 예측 성능을 평가하였습니다.
📌 문제: 구직자 데이터 전처리 및 분석
한 기업에서 구직자의 프로필 데이터를 분석하여 채용 가능성을 예측하려고 합니다.데이터를 분석하기 전에 먼저 전처리 과정을 수행해야 합니다.
📌 전처리 단계
아래 지침에 따라 데이터를 정리한 후, 이를 활용하여 분석을 수행하세요.
- 분석에 필요하지 않은 컬럼 제거
- city, company_size, company_type 컬럼을 삭제하세요.
- 결측값 처리
- 문자열 데이터(object 타입) 중 하나라도 결측치가 있는 행은 제거하세요.
- 이상치 처리 및 형 변환
- experience 변수 값이 >20 또는 <1인 행을 제거하고, 해당 변수를 **정수형(int)**으로 변환하세요.
- 특정 값 제거 및 형 변환
- last_new_job 변수 값이 >4 또는 'never'인 행을 제거하고, 해당 변수를 **정수형(int)**으로 변환하세요.
- 전처리 완료 후 데이터 개수 확인
- 전처리 후 데이터의 행 개수가 7,522개가 되어야 합니다.
📌 메인 문제
전처리된 데이터를 활용하여 구직자의 채용 가능성을 분석하세요.
🔹 서브 문제 1
구직자의 education_level과 experience 간의 관계를 분석하세요.
🔹 서브 문제 2
relevant_experience 여부에 따라 채용된 비율을 비교하세요.
🔹 서브 문제 3
산업 분야(industry)별 평균 경험(experience)을 비교하여 가장 높은 산업군을 찾으세요.
이 문제를 해결하면서 데이터 전처리, 결측값 처리, 이상치 제거, 형 변환, 그룹화 분석 등을 수행해야 합니다.
Python을 이용하여 문제를 해결하세요. 🚀
#답
1. 데이터 전처리
전처리 과정은 주어진 규칙을 따르며 데이터를 정리하는 단계입니다. 코드는 아래와 같습니다.
import pandas as pd
# 예시 데이터 로드 (데이터는 예시이므로 실제 파일 경로를 입력해야 합니다)
# df = pd.read_csv('data.csv')
# 1. 분석에 필요하지 않은 컬럼 제거
df = df.drop(columns=['city', 'company_size', 'company_type'])
# 2. 결측값 처리 (문자열 데이터 중 결측치가 있는 행 제거)
df = df.dropna(subset=df.select_dtypes(include=['object']).columns)
# 3. 이상치 처리 및 형 변환: 'experience'가 1 이상 20 이하인 값만 남기고, 정수형으로 변환
df = df[(df['experience'] > 1) & (df['experience'] < 20)]
df['experience'] = df['experience'].astype(int)
# 4. 특정 값 제거 및 형 변환: 'last_new_job' 값이 >4 또는 'never'인 행 제거하고, 정수형으로 변환
df = df[~df['last_new_job'].isin(['>4', 'never'])]
df['last_new_job'] = df['last_new_job'].astype(int)
# 5. 전처리 후 데이터 개수 확인
print(f"전처리 후 데이터 개수: {df.shape[0]}")
2. 메인 문제 해결
서브 문제 1: 구직자의 education_level과 experience 간의 관계 분석
education_level과 experience 간의 관계를 시각화하거나 통계적으로 분석할 수 있습니다. 아래는 이를 분석하는 코드입니다.
import seaborn as sns
import matplotlib.pyplot as plt
# education_level과 experience 간의 관계 분석
plt.figure(figsize=(10, 6))
sns.boxplot(data=df, x='education_level', y='experience')
plt.title('Education Level vs Experience')
plt.show()
서브 문제 2: relevant_experience 여부에 따라 채용된 비율 비교
relevant_experience가 있는지에 따라 채용 여부(hired)와의 비율을 비교할 수 있습니다. 아래는 이를 분석하는 코드입니다.
# 'relevant_experience'와 'hired' 비율 비교
hired_by_relevant_experience = df.groupby('relevant_experience')['hired'].mean()
print(hired_by_relevant_experience)
서브 문제 3: 산업 분야(industry)별 평균 경험(experience) 비교
산업별 평균 경험을 계산하고 가장 높은 값을 가진 산업군을 찾습니다.
# 산업별 평균 경험 계산
average_experience_by_industry = df.groupby('industry')['experience'].mean()
# 가장 높은 산업군 찾기
most_experience_industry = average_experience_by_industry.idxmax()
print(f"가장 높은 평균 경험을 가진 산업군: {most_experience_industry}")
전체 코드
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 데이터 로드
# df = pd.read_csv('data.csv')
# 1. 분석에 필요하지 않은 컬럼 제거
df = df.drop(columns=['city', 'company_size', 'company_type'])
# 2. 결측값 처리
df = df.dropna(subset=df.select_dtypes(include=['object']).columns)
# 3. 이상치 처리 및 형 변환: 'experience'가 1 이상 20 이하인 값만 남기고, 정수형으로 변환
df = df[(df['experience'] > 1) & (df['experience'] < 20)]
df['experience'] = df['experience'].astype(int)
# 4. 특정 값 제거 및 형 변환: 'last_new_job' 값이 >4 또는 'never'인 행 제거하고, 정수형으로 변환
df = df[~df['last_new_job'].isin(['>4', 'never'])]
df['last_new_job'] = df['last_new_job'].astype(int)
# 5. 전처리 후 데이터 개수 확인
print(f"전처리 후 데이터 개수: {df.shape[0]}")
# 서브 문제 1: education_level과 experience 간의 관계 분석
plt.figure(figsize=(10, 6))
sns.boxplot(data=df, x='education_level', y='experience')
plt.title('Education Level vs Experience')
plt.show()
# 서브 문제 2: relevant_experience 여부에 따른 채용된 비율 비교
hired_by_relevant_experience = df.groupby('relevant_experience')['hired'].mean()
print(hired_by_relevant_experience)
# 서브 문제 3: 산업별 평균 경험 비교
average_experience_by_industry = df.groupby('industry')['experience'].mean()
most_experience_industry = average_experience_by_industry.idxmax()
print(f"가장 높은 평균 경험을 가진 산업군: {most_experience_industry}")
결과
- 서브 문제 1: 교육 수준과 경험의 관계를 시각적으로 확인할 수 있습니다.
- 서브 문제 2: relevant_experience가 채용 여부에 미치는 영향을 확인할 수 있습니다.
- 서브 문제 3: 각 산업군별 평균 경험을 계산하여 가장 높은 산업군을 찾을 수 있습니다.
위 코드를 사용하여 데이터 분석을 진행하면 됩니다!
'Data Science > 실습' 카테고리의 다른 글
| pandas.Series.str 접근자와 정규표현식 (1) | 2025.02.03 |
|---|---|
| 이.데.분 01 - 탐색적 데이터 분석(EDA) (0) | 2025.02.02 |
| 이.데.분 - 이것이 데이터 분석이다 with 파이썬 (0) | 2025.02.01 |
| KMeans와 Silhouette Score를 활용한 클러스터링 평가 (0) | 2024.12.14 |
| A_1['B'].value_counts(nomalize = True) 와 pd.crosstab(A, B, nomalize = True) 가 다른 이유? (2) | 2024.12.09 |