In [1]:
import numpy as np
import pandas as pd
%pylab inline


Populating the interactive namespace from numpy and matplotlib

Загрузка данных


In [2]:
train_data = pd.read_csv('./data/evo_train.csv', sep=',', header=0)
test_data = pd.read_csv('./data/evo_test.csv', sep=',', header=0)

In [3]:
print train_data.shape
print test_data.shape


(55860, 3)
(37240, 2)

In [4]:
train_data.head()


Out[4]:
NAME GROUP_ID id
0 Пиво "Жигулевское" 0,5 л. св. 35 0
1 СОУС ТОМАТНЫЙ БУЗДЯК 670Г ТАТАРСКИЙ /8 6 1
2 Сигареты Esse SS Exchange 7 2
3 Петрушка 6 3
4 пиво ягерь 35 4

Выходная переменная


In [5]:
train_data.GROUP_ID.value_counts()


Out[5]:
7     6045
6     6014
24    5975
14    5972
34    5963
35    5957
30    3050
26    2999
25    2961
29     639
28     633
9      626
37     618
17     616
18     613
16     612
20     608
59     607
27     606
19     604
22     603
21     587
52     586
60     584
36     572
12     568
38     394
15     235
32      13
Name: GROUP_ID, dtype: int64

Посмотрим самые частые и самые редкие категории.


In [6]:
train_data[train_data.GROUP_ID == 6]['NAME'].head(10)


Out[6]:
1                СОУС ТОМАТНЫЙ БУЗДЯК 670Г ТАТАРСКИЙ /8
3                                              Петрушка
5     Детский мармелад "Trolls" Черничка Лакомства д...
33    КОЛБАСА В/К ОХЛ САЛЯМИ ФОРТУНА (ИНД) ИШИМСКИЙ ...
34                                         Кексы шокол.
36                 ШОК.БАТОНЧИК СНИКЕРС лесной орех 81г
37                                     Салат   "Цезарь"
39     Олимп Вэй Протеин Комплекс 2.27 кг. крем печенье
61    КИСЛИЦА ЖЕВ. РЕЗИНКА С ФРУКТОВОЙ НАЧ. (СРОК 12...
66    ТЕМНЫЙ ШОКОЛАД С ЦЕЛЬНЫМИ ЛЕСНЫМИ ОРЕХАМИ 100Г...
Name: NAME, dtype: object
  • 7 = сигареты
  • 6 = продукты питания
  • 32 = позиция по свободной цене

Предобработка данных

!!По-хорошему:

  1. К нижнему регистру
  2. Вычистить стоп-слова и знаки препинания
  3. Лемматизация
  4. CountVectorizer, TFIDF, Word2Vec

In [7]:
# удаление спецсимволов
import re

def remove_special_character(somestring):
    pattern = re.compile(u'[^a-zA-Zа-яА-Я0-9_]+')
    tokens = pattern.sub(' ', somestring).strip()
    return tokens

train_data['NAME'] = train_data['NAME'].str.decode('utf-8')
train_data['NAME'] = train_data['NAME'].apply(remove_special_character)

test_data['NAME'] = test_data['NAME'].str.decode('utf-8')
test_data['NAME'] = test_data['NAME'].apply(remove_special_character)

In [8]:
# лемматизация
from pymystem3 import Mystem

m = Mystem()
def lemmatize(text):
    lemmas = m.lemmatize(text)
    return (''.join(lemmas)).strip()

train_data['NAME'] = train_data['NAME'].apply(lemmatize)
test_data['NAME'] = test_data['NAME'].apply(lemmatize)

In [11]:
test_data.head(10)


Out[11]:
NAME id
0 пиво рижский светлый 0 5л 0
1 плавленый сыр король сыр 80г 1
2 заказ имл 7500342101814 2
3 мерриес трусики М58 3
4 лупа канц маленький 4
5 шампунь ЧЛ укрепление и уход 400мл 5
6 серьга пуссета 6
7 краска Igora Royal 8 4 7
8 зубочистик косточка кальциевый вкус курица д с... 8
9 вешалка кружева 5 9

In [13]:
train_data.to_csv('./data/lem_train_data.csv', header=True, index=False, encoding='utf-8', sep=';')
test_data.to_csv('./data/lem_test_data.csv', header=True, index=False, encoding='utf-8', sep=';')

Эксперимент с TF-IDF и RF


In [10]:
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier

In [14]:
max_features = range(4000, 7000, 1000)

for mf in max_features:
    cv = TfidfVectorizer(max_features=mf)
    cv_train_data = cv.fit_transform(train_data['NAME'])
    rf = RandomForestClassifier(n_estimators=200, random_state=11)
    scores = cross_val_score(rf, cv_train_data, train_data['GROUP_ID'], cv=2, scoring='accuracy')
    
    print 'Max features: ', mf
    print 'Score: ', scores.mean()


Max features:  4000
Score:  0.875420502814
Max features:  5000
Score:  0.880486924108
Max features:  6000
Score:  0.884658124838

In [15]:
# пробное решение
cv = TfidfVectorizer(max_features=8000)
cv_train_data = cv.fit_transform(train_data['NAME'])
cv_test_data = cv.transform(test_data['NAME'])

rf = RandomForestClassifier(n_estimators=400, random_state=11)
rf.fit(cv_train_data, train_data['GROUP_ID'])


Out[15]:
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
            max_depth=None, max_features='auto', max_leaf_nodes=None,
            min_impurity_split=1e-07, min_samples_leaf=1,
            min_samples_split=2, min_weight_fraction_leaf=0.0,
            n_estimators=400, n_jobs=1, oob_score=False, random_state=11,
            verbose=0, warm_start=False)

In [16]:
predict_rf = rf.predict(cv_test_data)
test_data['GROUP_ID'] = predict_rf

In [17]:
test_data.head()


Out[17]:
NAME id GROUP_ID
0 пиво рижский светлый 0 5л 0 35
1 плавленый сыр король сыр 80г 1 6
2 заказ имл 7500342101814 2 9
3 мерриес трусики М58 3 21
4 лупа канц маленький 4 24

In [18]:
test_data[['id', 'GROUP_ID']].to_csv('res2_rf_3105.csv', sep=',', header=True, index=False)

NaiveBayes


In [19]:
from sklearn.naive_bayes import MultinomialNB

In [20]:
mnb = MultinomialNB()
scores = cross_val_score(mnb, cv_train_data, train_data['GROUP_ID'], cv=3, scoring='accuracy')

In [21]:
print scores


[ 0.83161567  0.83491757  0.83104949]

In [ ]: