今天是第十六天我們可以寫一個情緒分析系統,我們可以用Lstm去預測他的心情進而去安排給使用者的景點,以下是程式碼
情緒資料準備
import numpy as np
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Embedding, LSTM, Dense, Dropout
# 假設我們有一個更大的文本數據集和多分類情緒標籤
texts = ["I am happy today!", "I feel so sad...", "This is exciting!", "I am very anxious", "I am calm and relaxed"]
labels = ["Positive", "Negative", "Positive", "Anxiety", "Calm"]
# 將情緒標籤轉換為數字格式
label_dict = {"Positive": 0, "Negative": 1, "Anxiety": 2, "Calm": 3}
numeric_labels = [label_dict[label] for label in labels]
# 設置參數
max_words = 10000
max_len = 100
embedding_dim = 100
# 文本預處理
tokenizer = Tokenizer(num_words=max_words)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
word_index = tokenizer.word_index
data = pad_sequences(sequences, maxlen=max_len)
labels = to_categorical(np.asarray(numeric_labels))
# 建立模型
model = Sequential()
model.add(Embedding(input_dim=max_words, output_dim=embedding_dim, input_length=max_len))
model.add(LSTM(128, return_sequences=True))
model.add(Dropout(0.5)) # 加入 Dropout 以防止過擬合
model.add(LSTM(64))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4, activation='softmax')) # 多分類輸出
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 訓練模型
model.fit(data, labels, epochs=20, batch_size=32)
預測情緒
def predict_emotion(text):
sequence = tokenizer.texts_to_sequences([text])
data = pad_sequences(sequence, maxlen=max_len)
prediction = model.predict(data)
emotion_index = np.argmax(prediction)
emotion = list(label_dict.keys())[list(label_dict.values()).index(emotion_index)]
return emotion
input_text = "I feel extremely anxious today."
emotion = predict_emotion(input_text)
print(f"Predicted emotion: {emotion}")
景點推薦
destinations = {
"Positive": {
"Summer": ["Beach", "Amusement Park", "Sunny Park"],
"Winter": ["Ski Resort", "Hot Springs"]
},
"Negative": {
"Summer": ["Museum", "Quiet Library"],
"Winter": ["Art Gallery", "Mountain Retreat"]
},
"Anxiety": {
"Summer": ["Meditation Center", "Quiet Forest"],
"Winter": ["Hot Springs", "Peaceful Lake"]
},
"Calm": {
"Summer": ["Zen Garden", "Yoga Retreat"],
"Winter": ["Calm River", "Winter Forest"]
}
}
Lstm推薦景點
import random
def recommend_destination(emotion, season="Summer", preferences=None):
if preferences:
# 根據用戶偏好過濾景點
potential_places = [place for place in destinations[emotion][season] if place in preferences]
else:
potential_places = destinations[emotion][season]
if not potential_places:
return ["Home"] # 當無匹配結果時推薦回家
return random.choice(potential_places) # 隨機推薦一個景點
# 假設現在是夏天,用戶偏好海灘類景點
recommended_place = recommend_destination(emotion, season="Summer", preferences=["Beach", "Sunny Park"])
print(f"Recommended destination: {recommended_place}")
整合
input_text = "I feel extremely anxious today."
emotion = predict_emotion(input_text)
# 假設我們知道現在是冬天,用戶偏好是「寧靜的自然景觀」
recommended_place = recommend_destination(emotion, season="Winter", preferences=["Peaceful Lake", "Hot Springs"])
print(f"Based on your emotion ({emotion}), we recommend you to visit: {recommended_place}")
當然,我會逐步解釋這個程式碼的每一部分,以幫助你理解它是如何運作的。
首先,我們需要準備數據來訓練LSTM模型,這包括文本數據和對應的情緒標籤。
import numpy as np
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Embedding, LSTM, Dense, Dropout
# 假設我們有一個更大的文本數據集和多分類情緒標籤
texts = ["I am happy today!", "I feel so sad...", "This is exciting!", "I am very anxious", "I am calm and relaxed"]
labels = ["Positive", "Negative", "Positive", "Anxiety", "Calm"]
texts
:這是一些樣本句子,用於情緒分類。labels
:這些是對應的情緒標籤,表示每個句子的情緒。接下來,我們將情緒標籤轉換成數字格式,這樣模型可以理解和處理它們。
label_dict = {"Positive": 0, "Negative": 1, "Anxiety": 2, "Calm": 3}
numeric_labels = [label_dict[label] for label in labels]
label_dict
:這是個字典,用來將情緒轉換為數字標籤。numeric_labels
:將文字標籤轉換為數字標籤的列表。然後,我們進行文本的預處理和轉換,為LSTM模型做好準備。
max_words = 10000
max_len = 100
embedding_dim = 100
tokenizer = Tokenizer(num_words=max_words)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
word_index = tokenizer.word_index
data = pad_sequences(sequences, maxlen=max_len)
labels = to_categorical(np.asarray(numeric_labels))
max_words
:我們只考慮文本中最常見的10000個單詞。max_len
:每個文本序列的最大長度,如果文本太短,會用0來填充;太長則會被截斷。tokenizer
:這是用來將文本轉換為數字序列的工具。sequences
:將每個文本轉換為對應的數字序列。pad_sequences
:將序列填充或截斷到相同的長度max_len
。labels
:將數字標籤轉換為one-hot編碼,以適應多分類問題。接下來,我們構建了一個多層LSTM網絡,並用來進行情緒分類。
model = Sequential()
model.add(Embedding(input_dim=max_words, output_dim=embedding_dim, input_length=max_len))
model.add(LSTM(128, return_sequences=True))
model.add(Dropout(0.5)) # 加入 Dropout 以防止過擬合
model.add(LSTM(64))
model.add(Dense(32, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4, activation='softmax')) # 多分類輸出
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 訓練模型
model.fit(data, labels, epochs=20, batch_size=32)
Embedding
:將每個單詞編碼為向量,這些向量在嵌入層中被學習,input_dim
是詞彙表的大小,output_dim
是嵌入向量的維度。LSTM(128, return_sequences=True)
:這是第一層LSTM,128
是隱藏層的單元數量,return_sequences=True
表示每一個時間步都會返回輸出,以便下一層LSTM使用。Dropout(0.5)
:這是為了防止過擬合,每次訓練會隨機「丟棄」50%的神經元。LSTM(64)
:第二層LSTM,這層只返回最後的輸出,適合接下來的全連接層。Dense(32, activation='relu')
:一個全連接層,有32個神經元,使用ReLU激活函數。Dense(4, activation='softmax')
:最終輸出層,根據情緒類別數進行多分類(這裡是4類),softmax
確保輸出是概率分佈。訓練好模型後,我們可以預測新文本的情緒。
def predict_emotion(text):
sequence = tokenizer.texts_to_sequences([text])
data = pad_sequences(sequence, maxlen=max_len)
prediction = model.predict(data)
emotion_index = np.argmax(prediction)
emotion = list(label_dict.keys())[list(label_dict.values()).index(emotion_index)]
return emotion
input_text = "I feel extremely anxious today."
emotion = predict_emotion(input_text)
print(f"Predicted emotion: {emotion}")
predict_emotion
函數:接收一段文本,將其轉換為模型所需的數字序列,並通過模型進行預測。np.argmax(prediction)
返回預測中概率最高的類別索引,並將其轉換為對應的情緒標籤。根據預測的情緒和其他條件(如季節、偏好),我們推薦一個景點。
destinations = {
"Positive": {
"Summer": ["Beach", "Amusement Park", "Sunny Park"],
"Winter": ["Ski Resort", "Hot Springs"]
},
"Negative": {
"Summer": ["Museum", "Quiet Library"],
"Winter": ["Art Gallery", "Mountain Retreat"]
},
"Anxiety": {
"Summer": ["Meditation Center", "Quiet Forest"],
"Winter": ["Hot Springs", "Peaceful Lake"]
},
"Calm": {
"Summer": ["Zen Garden", "Yoga Retreat"],
"Winter": ["Calm River", "Winter Forest"]
}
}
destinations
:這是一個字典,根據情緒和季節,為每個情緒類別提供相應的推薦景點列表。import random
def recommend_destination(emotion, season="Summer", preferences=None):
if preferences:
potential_places = [place for place in destinations[emotion][season] if place in preferences]
else:
potential_places = destinations[emotion][season]
if not potential_places:
return ["Home"]
return random.choice(potential_places)
recommended_place = recommend_destination(emotion, season="Winter", preferences=["Peaceful Lake", "Hot Springs"])
print(f"Recommended destination: {recommended_place}")
recommend_destination
函數:根據情緒、季節、以及用戶偏好來推薦景點。如果有偏好,則優先考慮偏好中的景點;如果沒有可推薦的景點,返回「Home」。最後隨機選擇一個推薦的景點。將情緒預測和景點推薦系統整合起來:
input_text = "I feel extremely anxious today."
emotion = predict_emotion(input_text)
# 假設我們知道現在是冬天,用戶偏好是「寧靜的自然景觀」
recommended_place = recommend_destination(emotion, season="Winter", preferences=["Peaceful Lake", "Hot Springs"])
print(f"Based on your emotion ({emotion}), we recommend you to visit: {recommended_place}")
這樣的系統不僅能夠識別多種情緒,還能根據用戶的情況提供個性化的旅遊建議,增強用戶體驗。