我正在嘗試將我的機器學習樸素貝葉斯情感分析模型部署到 Web 應用程式上。這個想法是用戶應該輸入一些文本,應用程式對其進行情感分析,然后將具有指定情感的文本存盤在資料庫中的另一列中,稍后通過 html 將其作為串列呼叫。
雖然模型和矢量化器在 Google Colab 上運行良好,但當我將模型加載到我的應用程式并嘗試通過它運行用戶輸入時,它將無法正常作業。根據我嘗試過的不同解決方案,我收到了許多錯誤代碼。
最新的是:
ValueError: DataFrame constructor not properly called!
但是當我嘗試解決這個問題時,我收到了其他錯誤訊息,例如:
'numpy.ndarray' object has no attribute 'lower'
或者:
ValueError: X has 1 features, but MultinomialNB is expecting 26150 features as input.
或者:
sklearn.exceptions.NotFittedError: Vocabulary not fitted or provided
基本上我不知道我在做什么,而且我幾個星期以來一直在試圖弄清楚。我的傾向是,問題要么是模型無法讀取來自用戶的格式,要么是矢量化器無法處理輸入。
或者也許我的整個方法是錯誤的,并且我遺漏了一些步驟。對此的任何幫助將不勝感激。
我的模型代碼如下(預處理后):
#Split into training and testing data
x = df['text']
y = df['sentiment']
df1 = df[df["text"].notnull()]
x1 = df1['text']
y1 = df1['sentiment']
x1_train, x1_test, y1_train, y1_test = train_test_split(x1, y1, test_size=0.2, random_state=30)
# Vectorize text
vec = CountVectorizer(stop_words='english')
x1 = vec.fit_transform(x1).toarray()
x1_test = vec.transform(x1_test).toarray()
df1 = df1.replace(r'^\s*$', np.nan, regex=True)
from sklearn.naive_bayes import MultinomialNB
sentiment_model = MultinomialNB()
sentiment_model.fit(x1, y1)
sentiment_model.score(x1_test, y1_test)
# Save model to disk
pickle.dump(sentiment_model, open('sentiment_model.pkl','wb'))
我的應用程式代碼如下所示:
@app.route('/journal', methods=['GET', 'POST'])
def entry():
if request.method == 'POST':
journals = request.form
entry_date = journals['entry_date']
journal_entry = journals['journal_entry']
vec = CountVectorizer(stop_words='english')
sdf = pd.DataFrame('journal_entry')
sdf = vec.fit_transform(sdf).toarray()
sdf = vec.transform(sdf).toarray()
sentiment = sentiment_model.predict(sdf)
journals['sentiment'] = sentiment
cur = mysql.connection.cursor()
#insert the values with sentiment attribute into database
cur.execute("INSERT INTO journals(entry_date, journal_entry, sentiment) VALUES(%s, %s, %s)",(entry_date, journal_entry, sentiment))
mysql.connection.commit()
return render_template('journal.html')
uj5u.com熱心網友回復:
對于開始這一旅程的人來說,資料科學管道可能會很棘手。當前代碼只有一個主要問題。您正在使用每個新傳入資料重新創建預處理步驟。您訓練模型的矢量化器不再使用,因此特征不匹配。請記住,我們只.fit_tranform在試穿/訓練期間。當我們使用它時,我們只.transform.
您可以像使用模型一樣保存經過訓練的矢量化器來修復它。然后將在 API 端點上使用模型和向量化器model.predict(vec.transform(data))。
更好的方法是將您的預處理(向量化器)和分類器合并為一個。
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
sentiment_model = Pipeline(
steps=[
(
"count_verctorizer",CountVectorizer(stop_words='english')
),
(
"naive_bayes",
MultinomialNB()
)
])
# now, it performs transformation in a pipeline
sentiment_model.fit(X1, y1)
# now we can use it/save it to use in our API we’re you will only need the model as the model will do `vectorizer tranform` for you
在 API 上,如果還沒有執行任何值和正則運算式,您可以確保其他過濾步驟。如果需要,您可以將這些添加到管道中。
uj5u.com熱心網友回復:
所以在我看來,這里有多個問題在起作用。
一方面,sdf = pd.DataFrame('journal_entry')沒有意義——您從文字字串“journal_entry”創建資料框,而不是它的實際內容?我建議您entry完全擺脫函式中的 DataFrame ,因為它不是 sklearn 物件所需的輸入結構。
其次,您通過呼叫復制功能,fit_transform然后transform在您的entry函式中再次復制。呼叫fit_transform就足夠了,因為它正在做兩件事:1)它學習字典 2)它轉換為檔案術語矩陣。
第三,您使用特定的 CountVectorizer 模型訓練模型。該模型將使用學習的檔案項矩陣將每個檔案轉換為向量,該矩陣在您呼叫fit或fit_transform函式時獲得固定大小。然后使用這個固定大小的向量訓練您的樸素貝葉斯模型。因此,當它在推理時獲得不同大小的向量時,它會抱怨——這是因為您CountVectorizer在每次entry呼叫時都會再次重新初始化。您需要保存CountVectorizer,以及如果你想保留的特征尺寸。
此外,我建議對您的entry函式進行一些檢查,以確保您在 POST 請求中獲得有效的演算法字串。
# load both CountVectorizer and the model
vec = pickle.load(open("my_count_vec.pkl", "rb"))
sentiment_model = pickle.load(open("my_sentiment_model", "rb"))
@app.route('/journal', methods=['GET', 'POST'])
def entry():
if request.method == 'POST':
journals = request.form
entry_date = journals['entry_date']
journal_entry = journals['journal_entry']
sdf = vec.transform([journal_entry]).reshape(1, -1)
sentiment = sentiment_model.predict(sdf)
...
sdf = vec.transform([journal_entry]).reshape(1, -1) 假設日志條目是單個字串,因此需要重新整形以進行進一步處理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/390989.html
標籤:Python 分类 情感分析 朴素贝叶斯 计数向量化器
