[MachinLearning001] 스크래핑데이터 분석하기
01. 상품 키워드화작업
객관화, 데이터화시키기위해
NLTK (Natural Language Toolkit)
자연어 처리(NLP)와 언어 분석을 위해 다양한 모듈, 데이터셋, 알고리즘제공
사용법
–토큰화 (Tokenization) : 텍스트를 문장이나 단어단위로 분류
- 형태소 분석 (Part of Speach Tagging) 각 단어의 품사를 식별한다.
[ 데이터 분석하기 ]
사이킷런 Machine Learning
** 에러
sklearn 설치시 pycharm 에서 설치에러남
deprecated sklearn package, use scikit-learn instead
** 에러
Feature names are only supported if all input features have string names, but your input has ['int', 'str'] as feature name / column name types. If you want feature names to be stored and validated, you must convert them all to strings, by using X.columns = X.columns.astype(str) for example. Otherwise you can remove feature / column names from your input data, or convert them all to a non-string data type.
특징 이름이 문자열로 일관되어야 함을 나타냅니다. 이는 CountVectorizer를 사용하여 벡터화한 제목 데이터와 price 및 star 열을 결합할 때 발생합니다. 모든 열 이름을 문자열로 변환하면 이 문제를 해결할 수 있습니다.
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
from tabulate import tabulate
def machine_01(analize_array):
print(analize_array)
print(f"분석 대상 데이터 : {len(analize_array)}")
# for i, item in enumerate(analize_array):
# print(item.get("keyword"))
# 예시 데이터 (new_array를 pandas DataFrame으로 변환)
data = pd.DataFrame(analize_array)
# 시각적으로 표현
print(tabulate(data, headers='keys', tablefmt='psql'))
# 예시 데이터 (여기서는 title, price, buy, star만 사용)
data['price'] = data['price'].str.replace('$', '').astype(float) # 가격 데이터 정리
data['buy'] = data['buy'].astype(int) # 구매 횟수 정리
data['star'] = data['star'].astype(float) # 별점 정리
# 2. 특징 추출
# 텍스트 데이터를 벡터화
vectorizer = CountVectorizer()
title_vectorized = vectorizer.fit_transform(data['title'])
# 숫자 특징 결합
title_df = pd.DataFrame(title_vectorized.toarray(), columns=vectorizer.get_feature_names_out())
numeric_features = data[['price', 'star']].reset_index(drop=True)
# 모든 열 이름을 문자열로 변환
title_df.columns = title_df.columns.astype(str)
numeric_features.columns = numeric_features.columns.astype(str)
# 특징 결합
features = pd.concat([title_df, numeric_features], axis=1)
# 3. 모델 학습
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(features, data['buy'], test_size=0.2, random_state=42)
# 모델 학습
model = RandomForestClassifier()
model.fit(X_train, y_train)
# 4. 평가 및 개선
y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
print("Classification Report:")
print(classification_report(y_test, y_pred))
코드 설명 01
# 예시 데이터 (new_array를 pandas DataFrame으로 변환)
data = pd.DataFrame(analize_array)
# 시각적으로 표현
print(tabulate(data, headers='keys', tablefmt='psql'))
# 예시 데이터 (여기서는 title, price, buy, star만 사용)
data['price'] = data['price'].str.replace('$', '').astype(float) # 가격 데이터 정리
data['buy'] = data['buy'].astype(int) # 구매 횟수 정리
data['star'] = data['star'].astype(float) # 별점 정리
엑셀 테이블을 만든다고 생각하면 쉽다.
아래와같은 테이블이 만들어진다 ( tabulate 라이브러리사용 )

코드 설명 02
# 2. 특징 추출
# 텍스트 데이터를 벡터화
vectorizer = CountVectorizer()
title_vectorized = vectorizer.fit_transform(data['title'])
CountVectorizer는 텍스트 데이터를 벡터화하는 데 사용되는 매우 중요한 도구입니다.
주로 자연어 처리(NLP)에서 사용되며, 텍스트 데이터를 머신러닝 모델에서 사용할 수 있는 수치 데이터로 변환합니다
ountVectorizer의 역할
- 텍스트 전처리: 입력된 텍스트 데이터에서 불용어(stop words)를 제거하고, 모든 단어를 소문자로 변환하며, 구두점 등을 제거합니다.
- 어휘 사전 생성: 텍스트 데이터에서 모든 고유한 단어들의 목록을 생성합니다.
- 단어 수 카운팅: 각 문서(예: 각 제품의 제목)에서 각 단어가 등장하는 횟수를 세어 벡터로 변환합니다.
문서-단어 행렬(Document-Term Matrix, DTM)
서의 텍스트 데이터를 수치 데이터로 변환하는 방법
행은 개별 문서를 나타내고, 각 열은 어휘 사전의 단어로표현하여 행렬화한다.
세 개의 문서(제품 제목)가 있다고 가정해봅시다:
- "Cheap laptop"
- "Cheap smartphone"
- "Expensive laptop"
단계별 설명
어휘 사전 생성:
- 모든 문서에서 고유한 단어들을 모아서 어휘 사전을 만듭니다.
- 이 예시에서는 어휘 사전이
["cheap", "laptop", "smartphone", "expensive"]입니다.
문서-단어 행렬 생성:
- 각 문서를 어휘 사전의 단어들에 대한 등장 횟수로 표현한 벡터로 변환합니다.
- 이를 통해 각 문서가 벡터 형태로 표현됩니다.
예시
| 문서 번호 | 문서 내용 |
|---|---|
| 1 | Cheap laptop |
| 2 | Cheap smartphone |
| 3 | Expensive laptop |
어휘 사전: ["cheap", "laptop", "smartphone", "expensive"]
| 단어 | 문서 1 | 문서 2 | 문서 3 |
|---|---|---|---|
| cheap | 1 | 1 | 0 |
| laptop | 1 | 0 | 1 |
| smartphone | 0 | 1 | 0 |
| expensive | 0 | 0 | 1 |
결과 행렬
이제 각 문서를 벡터로 표현할 수 있습니다:
- 문서 1: "Cheap laptop" →
[1, 1, 0, 0] - 문서 2: "Cheap smartphone" →
[1, 0, 1, 0] - 문서 3: "Expensive laptop" →
[0, 1, 0, 1]
결론
이 과정에서 각 제목이 단어 빈도로 구성된 벡터로 변환
숫자 특징 결합
title_df = pd.DataFrame(title_vectorized.toarray(), columns=vectorizer.get_feature_names_out())
numeric_features = data[['price', 'star']].reset_index(drop=True)
목표: 텍스트 데이터와 숫자 데이터를 하나의 데이터프레임으로 결합
price와 star 열을 별도의 데이터프레임으로 저장
인덱스를 재설정하여 벡터화된 데이터와 동일한 인덱스를 가지도록 합니다.
price star
0 10.99 4.5
1 20.99 4.7
2 30.99 4.6
- 첫 번째 행은 첫 번째 문서("Cheap laptop")의 가격과 별점을 나타냅니다.
- 두 번째 행은 두 번째 문서("Cheap smartphone")의 가격과 별점을 나타냅니다.
- 세 번째 행은 세 번째 문서("Expensive laptop")의 가격과 별점을 나타냅니다.
모든 열 이름을 문자열로 변환
# 모든 열 이름을 문자열로 변환
title_df.columns = title_df.columns.astype(str)
numeric_features.columns = numeric_features.columns.astype(str)
목표: 데이터프레임의 모든 열 이름을 문자열로 변환하여 오류를 방지
특징 결합
목표: 텍스트 특징과 숫자 특징을 결합하여 최종 특징 데이터프레임을 생성
pd.concat을 사용하여 텍스트 데이터프레임과 숫자 데이터프레임을 결합합니다.
axis=1은 열 단위로 결합함을 의미합니다.
# 특징 결합
features = pd.concat([title_df, numeric_features], axis=1)
print(features)
cheap expensive laptop smartphone price star
0 1 0 1 0 10.99 4.5
1 1 0 0 1 20.99 4.7
2 0 1 1 0 30.99 4.6
이 최종 데이터프레임은 텍스트 데이터(단어 빈도)와 숫자 데이터(가격, 별점)를 모두 포함하며, 머신러닝 모델에 사용할 수 있는 형태로 변환된 것입니다.
# 3. 모델 학습
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(features, data['buy'], test_size=0.2, random_state=42)
- train_test_split 함수는 scikit-learn 라이브러리의 중요한 함수 중 하나
- 데이터를 학습 세트(Training Set)와 테스트 세트(Test Set)로 나누는 데 사용
- 목적: 주어진 데이터를 두 부분으로 나누어 하나는 모델 학습에 사용하고, 다른 하나는 모델 평가에 사용하기 위함
주요 매개변수
X: 입력 데이터(features)features변수는 모델이 학습할 수 있도록 제공하는 입력 데이터입니다. 여기서는 텍스트 데이터를 벡터화한 결과와 수치 데이터를 결합한 데이터프레임입니다.
y: 출력 데이터(target)data['buy']변수는 각 샘플의 출력 값입니다. 여기서는 제품의 구매 횟수를 나타냅니다.
test_size: 테스트 세트의 비율test_size=0.2는 전체 데이터 중 20%를 테스트 세트로 할당하겠다는 의미입니다.
random_state: 무작위 시드random_state=42는 데이터 분할을 무작위로 하되, 동일한 시드 값을 사용하여 실행할 때마다 동일한 결과를 얻도록 합니다.
random_state는 무작위성을 제어하는 파라미터
데이터를 학습 세트와 테스트 세트로 나눌 때 무작위로 나누게 되는데, random_state 값을 설정하면 실행할 때마다 동일한 분할 결과를 얻을 수 있습니다.
시드값(seed value)는 컴퓨터 프로그램에서 난수 생성기의 초기값을 의미
features: 입력 데이터
cheap expensive laptop smartphone price star
0 1 0 1 0 10.99 4.5
1 1 0 0 1 20.99 4.7
2 0 1 1 0 30.99 4.6
data['buy']: 출력 데이터
0 100
1 150
2 200
데이터 분할 후 결과:
X_train: 학습 세트 입력 데이터 (80%의 데이터)X_test: 테스트 세트 입력 데이터 (20%의 데이터)y_train: 학습 세트 출력 데이터 (80%의 데이터)y_test: 테스트 세트 출력 데이터 (20%의 데이터)
# 모델 학습
model = RandomForestClassifier()
model.fit(X_train, y_train)
# 4. 평가 및 개선
y_pred = model.predict(X_test)
RandomForestClassifier()는 랜덤 포레스트 분류기 모델을 초기화합니다.
랜덤 포레스트는 다수의 결정 트리를 사용하여 앙상블 학습을 수행하는 알고리즘입니다. 이는 높은 예측 정확도와 과적합 방지에 효과적입니다.
model.fit(X_train, y_train)는 학습 데이터를 사용하여 모델을 학습시킵니다.
X_train은 학습 세트의 특징 데이터, y_train은 학습 세트의 타겟 데이터입니다.
# 평가 지표 계산 및 출력
print("Accuracy:", accuracy_score(y_test, y_pred))
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
print("Classification Report:")
print(classification_report(y_test, y_pred))
확도(Accuracy):
accuracy_score(y_test, y_pred)는 예측값(y_pred)과 실제값(y_test)을 비교하여 정확도를 계산합니다.
Accuracy: 0.85 # 85%의 예측이 올바름
혼동 행렬(Confusion Matrix):
confusion_matrix(y_test, y_pred)는 예측 결과와 실제 결과를 비교하여 혼동 행렬을 생성합니다.
행은 실제 클래스, 열은 예측한 클래스
에러
UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
모델의 예측 결과 중 일부 클래스에 대해 정밀도(precision)가 정의되지 않는 경우 발생하는 경고

정밀도(precision)를 계산할 때 분모에 해당하는 값이 0이 되는 경우 때문
델이 어떤 클래스에 대해서도 True Positives가 없고, 그 클래스에 대해 예측한 샘플이 전혀 없다면, 분모가 0이 되어서 정밀도가 정의되지 않습니다.
zero_division 파라미터 사용: classification_report 함수의 zero_division 파라미터를 설정하여, 정의되지 않은 경우의 값을 지정할 수 있습니다.
해결책
print(classification_report(y_test, y_pred, zero_division=1))
모델을 로컬에 저장하여 계속학습시키기
import joblib
# 모델 학습
model = RandomForestClassifier()
model.fit(X_train, y_train)
# 모델 저장
joblib.dump(model, 'random_forest_model.pkl')
모델이 정확도가 떨어진다.
낮은 정확도의 원인 및 해결책
데이터 불균형:
- 특정 클래스의 샘플이 다른 클래스보다 훨씬 많은 경우, 모델이 대부분의 샘플을 다수 클래스에 속한다고 예측하게 될 수 있습니다.
- 해결책: SMOTE 등의 기법을 사용하여 데이터 균형을 맞추거나 클래스 가중치를 조정합니다.
모델 복잡성:
- 모델이 너무 단순하여 데이터의 패턴을 학습하지 못하는 경우, 예측 성능이 낮을 수 있습니다.
- 해결책: 더 복잡한 모델을 사용하거나, 하이퍼파라미터 튜닝을 통해 모델 성능을 개선합니다.
데이터 전처리:
- 데이터 전처리가 적절하지 않으면, 모델이 유의미한 패턴을 학습하기 어려울 수 있습니다.
- 해결책: 데이터 정규화, 이상치 처리, 특징 엔지니어링 등을 통해 데이터를 적절히 전처리합니다.
특징 선택:
- 사용된 특징들이 타겟 변수와의 관련성이 낮을 경우, 모델의 예측 성능이 낮을 수 있습니다.
- 해결책: 특징 선택 또는 생성 기법을 사용하여 유의미한 특징을 선택합니다.
모델 성능 평가
정확도 외에도 모델 성능을 평가하는 다양한 지표가 있습니다. 특히 불균형 데이터 세트에서는 정밀도(Precision), 재현율(Recall), F1 점수(F1 Score) 등의 지표를 함께 고려해야 합니다.
오늘의 결론
상품명, 가격, 별점을 가지고 판매가 잘되는 예측모델을 추출하는것은
상품명과 가격 별점과의 연관성이 부족하여 예측이 잘안된다.
데이터 추가가 필요해보인다.
혹은 전처리과정이필요해보인다


