Мы проводим анализ настроений в Jupyter. Код ниже описывает общий процесс. Мы можем прекрасно обучить модель, но когда мы пытаемся объединить ее с нашими фактическими данными, возникает проблема. Есть определенный момент, когда ядро продолжает перезагружаться - я отметил это ниже. Очевидно, мы ищем способ предотвратить это.
Данных много, и я попытался разделить их на части, но проблема все та же.
Код:
Определение методов очистки твитов:
tok = WordPunctTokenizer()
pat1 = r'@[A-Za-z0-9_]+'
pat2 = r'https?://[^ ]+'
combined_pat = r'|'.join((pat1, pat2))
www_pat = r'www.[^ ]+'
negations_dic = {"isn't":"is not", "aren't":"are not", "wasn't":"was not", "weren't":"were not",
"haven't":"have not","hasn't":"has not","hadn't":"had not","won't":"will not",
"wouldn't":"would not", "don't":"do not", "doesn't":"does not","didn't":"did not",
"can't":"can not","couldn't":"could not","shouldn't":"should not","mightn't":"might not",
"mustn't":"must not"}
neg_pattern = re.compile(r'\b(' + '|'.join(negations_dic.keys()) + r')\b')
def tweet_cleaner(text):
soup = BeautifulSoup(text, 'lxml')
souped = soup.get_text()
try:
bom_removed = souped.decode("utf-8-sig").replace(u"\ufffd", "?")
except:
bom_removed = souped
stripped = re.sub(combined_pat, '', bom_removed)
stripped = re.sub(www_pat, '', stripped)
lower_case = stripped.lower()
neg_handled = neg_pattern.sub(lambda x: negations_dic[x.group()], lower_case)
letters_only = re.sub("[^a-zA-Z]", " ", neg_handled)
words = []
for x in tok.tokenize(letters_only):
if len(x) > 1:
words = x
return (" ".join(words)).strip()
Загрузка и подготовка обучающих данных:
training_df = pd.read_csv('Clean Training Data', low_memory = False)
x = training_df.text
y = training_df.sentiment
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=.01, random_state=42)
Настройка векторизации TF-IDF и Logisti c Регрессия:
unigrams = (1,1)
bigrams = (2,2)
trigrams = (3,3)
uni_and_bigrams = (1,2)
bi_and_trigrams = (2,3)
uni_bi_and_trigrams = (1,3)
def get_tfidf_features(train_fit, ngrams=(1,1)):
vector = TfidfVectorizer(ngrams, sublinear_tf=True)
vector.fit(train_fit)
return vector
tf_vector = get_tfidf_features(training_df['text'])
X = tf_vector.transform(training_df['text'])
y = training_df['sentiment']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.01, random_state = 42)
LR_model = LogisticRegression(solver='lbfgs', max_iter = 1000)
LR_model.fit(X_train, y_train)
y_predict_lr = LR_model.predict(X_test)
conmat = np.array(confusion_matrix(y_test, y_predict_lr, labels=[1,0]))
confusion = pd.DataFrame(conmat, index=['positive', 'negative'], columns=['predicted_positive', 'predicted_negative'])
Импорт фактических данных:
df = pd.read_csv('TRANSLATED/02-01 translated', low_memory = False, lineterminator='\n')
df = df.drop(columns=['user_default_profile_image', 'retweet_screen_name', 'in_reply_to_status_id',
'in_reply_to_user_id', 'possibly_sensitive', 'in_reply_to_screen_name',
'user_listed_count', 'in_reply_to_status_id', 'user_screen_name',
'user_description', 'user_favourites_count', 'user_followers_count',
'user_friends_count', 'user_screen_name.1', 'user_created_at',
'user_statuses_count', 'user_time_zone', 'user_verified',
'coordinates', 'source', 'tweet_url',
'urls', 'id', 'place',
'user_name', 'user_urls', 'reweet_id',
'coordinates', 'media'])
Преобразование created_at в формат datetime:
with tqdm(total=100, file=sys.stdout) as pbar:
for i in tqdm(range(len(df))):
try:
df.loc[i, 'created_at'] = pd.to_datetime(df.loc[i, 'created_at'])
except:
pass
Чистый текст:
with tqdm(total=100, file=sys.stdout) as pbar:
for txt in tqdm(df['text']):
txt = tweet_cleaner(txt)
Проблема:
Существует проблема с количеством функций, на которых мы обучили модель, и количеством функций, к которым мы хотим применить обученную модель с нашими фактическими данными. Модель обучена на 200000 уникальных слов - фактические данные имеют другое число. Это то, что мы придумали для решения этой проблемы, но определенно думаем, что есть способ лучше. Прямо сейчас строка LR_model.predict(X_df1)
вызывает перезапуск ядра каждый раз.
tfidf = TfidfVectorizer()
X_df = tfidf.fit_transform(df['text'])
X1 = pd.DataFrame.sparse.from_spmatrix(X)
X_df1 = pd.DataFrame.sparse.from_spmatrix(X_df)
not_existing_cols = [c for c in X1.columns.tolist() if c not in X_df1]
X_df1 = X_df1.reindex(X_df1.columns.tolist() + not_existing_cols, axis=1)
X_df.fillna(0, inplace=True)
a = LR_model.predict(X_df1)
df['sentiment'] = a
# remove hrs/mins/secs from the dates
df['created_at'] = df['created_at'].dt.date
Пожалуйста, дайте мне знать, если вы знаете, что здесь не так!