Я работаю над проблемой классификации ярлыков эмоций, которую нужно решить с помощью word2ve c. это мой код, который я выучил из пары уроков. сейчас точность очень низкая. около 0,02, который говорит мне, что что-то не так в моем коде. но я не могу найти это. я пробовал этот код для TF-IDF и BOW (очевидно, за исключением части word2ve c) и получил гораздо лучшие показатели точности, такие как 0,28, но кажется, что этот код как-то не так:
np.set_printoptions(threshold=sys.maxsize)
wv = gensim.models.KeyedVectors.load_word2vec_format("E:\\GoogleNews-vectors-negative300.bin", binary=True)
wv.init_sims(replace=True)
#Pre-Processor Function
pre_processor = TextPreProcessor(
omit=['url', 'email', 'percent', 'money', 'phone', 'user',
'time', 'url', 'date', 'number'],
normalize=['url', 'email', 'percent', 'money', 'phone', 'user',
'time', 'url', 'date', 'number'],
segmenter="twitter",
corrector="twitter",
unpack_hashtags=True,
unpack_contractions=True,
tokenizer=SocialTokenizer(lowercase=True).tokenize,
dicts=[emoticons]
)
#Averaging Words Vectors to Create Sentence Embedding
def word_averaging(wv, words):
all_words, mean = set(), []
for word in words:
if isinstance(word, np.ndarray):
mean.append(word)
elif word in wv.vocab:
mean.append(wv.syn0norm[wv.vocab[word].index])
all_words.add(wv.vocab[word].index)
if not mean:
logging.warning("cannot compute similarity with no input %s", words)
# FIXME: remove these examples in pre-processing
return np.zeros(wv.vector_size,)
mean = gensim.matutils.unitvec(np.array(mean).mean(axis=0)).astype(np.float32)
return mean
def word_averaging_list(wv, text_list):
return np.vstack([word_averaging(wv, post) for post in text_list ])
#Secondary Word-Averaging Method
def get_mean_vector(word2vec_model, words):
# remove out-of-vocabulary words
words = [word for word in words if word in word2vec_model.vocab]
if len(words) >= 1:
return np.mean(word2vec_model[words], axis=0)
else:
return []
#Loading data
raw_train_tweets = pandas.read_excel('E:\\train.xlsx').iloc[:,1] #Loading all train tweets
train_labels = np.array(pandas.read_excel('E:\\train.xlsx').iloc[:,2:13]) #Loading corresponding train labels (11 emotions)
raw_test_tweets = pandas.read_excel('E:\\test.xlsx').iloc[:,1] #Loading 300 test tweets
test_gold_labels = np.array(pandas.read_excel('E:\\test.xlsx').iloc[:,2:13]) #Loading corresponding test labels (11 emotions)
print("please wait")
#Pre-Processing
train_tweets=[]
test_tweets=[]
for tweets in raw_train_tweets:
train_tweets.append(pre_processor.pre_process_doc(tweets))
for tweets in raw_test_tweets:
test_tweets.append(pre_processor.pre_process_doc(tweets))
#Vectorizing
train_array = word_averaging_list(wv,train_tweets)
test_array = word_averaging_list(wv,test_tweets)
#Predicting and Evaluating
clf = LabelPowerset(LogisticRegression(solver='lbfgs', C=1, class_weight=None))
clf.fit(train_array,train_labels)
predicted= clf.predict(test_array)
intersect=0
union=0
accuracy=[]
for i in range(0,3250): #i have 3250 test tweets.
for j in range(0,11): #11 emotions
if predicted[i,j]&test_gold_labels[i,j]==1:
intersect+=1
if predicted[i,j]|test_gold_labels[i,j]==1:
union+=1
accuracy.append(intersect/union) if union !=0 else accuracy.append(0.0)
intersect=0
union=0
print(np.mean(accuracy))
Результат :
0.4674498168498169
И я напечатал прогнозируемую переменную (для твитов от 0 до 10), чтобы увидеть, как она выглядит:
(0, 0) 1
(0, 2) 1
(2, 0) 1
(2, 2) 1
(3, 4) 1
(3, 6) 1
(4, 0) 1
(4, 2) 1
(5, 0) 1
(5, 2) 1
(6, 0) 1
(6, 2) 1
(7, 0) 1
(7, 2) 1
(8, 4) 1
(8, 6) 1
(9, 3) 1
(9, 8) 1
, как вы можете видеть, она показывает только 1. например, (6,2) означает в твите номер 6, эмоция номер 2 равна 1. (9,8) означает в твите номер 9, эмоция номер 8 равна 1. другие эмоции рассматриваются как 0. но вы можете представить себе это так чтобы лучше понять, что я сделал в методе Точность:
gold emotion for tweet 0: [1 1 0 0 0 0 1 0 0 0 1]
predicted emotion for tweet 0: [1 0 1 0 0 0 0 0 0 0 0]
я использовал объединение и пересечение для индексов один за другим. От 1 до 1. От 1 до 1. От 0 до 1, пока золотая эмоция 11 не предсказала эмоцию 11. Я сделал это для всех твитов в двух циклах.
Создание векторов Word2Ve c на моих твитах:
теперь я хочу использовать gensim для создания векторов Word2Ve c в моем наборе данных твита. я изменил некоторые части кода выше, как показано ниже:
#Averaging Words Vectors to Create Sentence Embedding
def word_averaging(wv, words):
all_words, mean = set(), []
for word in words:
if isinstance(word, np.ndarray):
mean.append(word)
elif word in wv.vocab:
mean.append(wv.syn0norm[wv.vocab[word].index])
all_words.add(wv.vocab[word].index)
if not mean:
logging.warning("cannot compute similarity with no input %s", words)
# FIXME: remove these examples in pre-processing
return np.zeros(wv.vector_size,)
mean = gensim.matutils.unitvec(np.array(mean).mean(axis=0)).astype(np.float32)
return mean
def word_averaging_list(wv, text_list):
return np.vstack([word_averaging(wv, post) for post in text_list ])
#Loading data
raw_aggregate_tweets = pandas.read_excel('E:\\aggregate.xlsx').iloc[:,0] #Loading all train tweets
raw_train_tweets = pandas.read_excel('E:\\train.xlsx').iloc[:,1] #Loading all train tweets
train_labels = np.array(pandas.read_excel('E:\\train.xlsx').iloc[:,2:13]) #Loading corresponding train labels (11 emotions)
raw_test_tweets = pandas.read_excel('E:\\test.xlsx').iloc[:,1] #Loading 300 test tweets
test_gold_labels = np.array(pandas.read_excel('E:\\test.xlsx').iloc[:,2:13]) #Loading corresponding test labels (11 emotions)
print("please wait")
#Pre-Processing
aggregate_tweets=[]
train_tweets=[]
test_tweets=[]
for tweets in raw_aggregate_tweets:
aggregate_tweets.append(pre_processor.pre_process_doc(tweets))
for tweets in raw_train_tweets:
train_tweets.append(pre_processor.pre_process_doc(tweets))
for tweets in raw_test_tweets:
test_tweets.append(pre_processor.pre_process_doc(tweets))
print(len(aggregate_tweets))
#Vectorizing
w2v_model = gensim.models.Word2Vec(aggregate_tweets, min_count = 10, size = 300, window = 8)
print(w2v_model.wv.vectors.shape)
train_array = word_averaging_list(w2v_model.wv,train_tweets)
test_array = word_averaging_list(w2v_model.wv,test_tweets)
, но я получаю эту ошибку:
TypeError Traceback (most recent call last)
<ipython-input-1-8a5fe4dbf144> in <module>
110 print(w2v_model.wv.vectors.shape)
111
--> 112 train_array = word_averaging_list(w2v_model.wv,train_tweets)
113 test_array = word_averaging_list(w2v_model.wv,test_tweets)
114
<ipython-input-1-8a5fe4dbf144> in word_averaging_list(wv, text_list)
70
71 def word_averaging_list(wv, text_list):
---> 72 return np.vstack([word_averaging(wv, post) for post in text_list ])
73
74 #Averaging Words Vectors to Create Sentence Embedding
<ipython-input-1-8a5fe4dbf144> in <listcomp>(.0)
70
71 def word_averaging_list(wv, text_list):
---> 72 return np.vstack([word_averaging(wv, post) for post in text_list ])
73
74 #Averaging Words Vectors to Create Sentence Embedding
<ipython-input-1-8a5fe4dbf144> in word_averaging(wv, words)
58 mean.append(word)
59 elif word in wv.vocab:
---> 60 mean.append(wv.syn0norm[wv.vocab[word].index])
61 all_words.add(wv.vocab[word].index)
62
TypeError: 'NoneType' object is not subscriptable