<jupyter_start><jupyter_text>[Построение и отбор признаков](https://habr.com/ru/company/ods/blog/325422/) **Сте́мминг** — это процесс нахождения основы слова для заданного исходного слова. Основа слова не обязательно совпадает с морфологическим корнем слова.  **Лемматиза́ция** — процесс приведения словоформы к лемме — её нормальной (словарной) форме.<jupyter_code># перед началом работы не забудьте скачать файл train.json.zip с Kaggle и разархивировать его
import json
import pandas as pd

# сразу загрузим датасет от Renthop
with open('./data/train.json', 'r') as raw_data:
    data = json.load(raw_data)
    df = pd.DataFrame(data)
from functools import reduce
import numpy as np

texts = [['i', 'have', 'a', 'cat'],
         ['he', 'have', 'a', 'dog'],
         ['he', 'and', 'i', 'have', 'a', 'cat', 'and', 'a', 'dog']]

dictionary = list(enumerate(set(reduce(lambda x, y: x + y, texts))))

def vectorize(text):
    vector = np.zeros(len(dictionary))
    for i, word in dictionary:
        num = 0
        for w in text:
            if w == word:
                num += 1
        if num:
            vector[i] = num
    return vector

for t in texts:
    print(vectorize(t))
from sklearn.feature_extraction.text import CountVectorizer
vect = CountVectorizer(ngram_range=(1,1)) 

vect.fit_transform(['no i have cows', 'i have no cows']).toarray()
print(vect.vocabulary_)
vect = CountVectorizer(ngram_range=(1,2)) 

vect.fit_transform(['no i have cows', 'i have no cows']).toarray()
print(vect.vocabulary_)<jupyter_output>{'no': 2, 'have': 1, 'cows': 0}
{'no': 4, 'have': 1, 'cows': 0, 'no have': 6, 'have cows': 2, 'have no': 3, 'no cows': 5}<jupyter_text>[Шпаргалка по CountVectorizer](http://zabaykin.ru/?p=463)<jupyter_code>from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
 
# инициализируем
vectorizer = CountVectorizer()
# составляем корпус документов
corpus = [
  'слово1 слово2 слово3',
  'слово2 слово3',
  'слово1 слово2 слово1',
  'слово4'
]
# подсчитываем
X = vectorizer.fit_transform(corpus)
 
# таким образом будет подсчитана следующая структура:
#        | слово1 | слово2 | слово3 | слово4
# текст1 |   1    |    1   |   1    |   0
# текст2 |   0    |    1   |   1    |   0
# текст3 |   2    |    1   |   0    |   0
# текст4 |   0    |    0   |   0    |   1
 
# чтобы получить сгенерированный словарь, из приведенной структуры CountVectorizer, 
# стоит отметить что порядок совпадает с матрицей
print(f"Words: {vectorizer.get_feature_names()}")  # ['слово1', 'слово2', 'слово3', 'слово4']
 
# чтобы узнать индекс токена в словаре
print(f"Get index: {vectorizer.vocabulary_.get('слово3')}") # вернет 2
print(f"All index: {vectorizer.vocabulary_}")

      # показать матрицу
print(f"Matrix: {X.toarray()}")

# теперь можно быстро подсчитать вектор для нового документа
print(f"New doc:\n{vectorizer.transform(['слово1 слово4 слово4'])}")
 
# чтобы узнать количественное вхождение каждого слова:
matrix_freq = np.asarray(X.sum(axis=0)).ravel()
# ravel сделать одномерным
print(f"Matrix frequency: {matrix_freq}")

final_matrix = np.array([np.array(vectorizer.get_feature_names()), matrix_freq])
print(f"Final matrix:\n{final_matrix}")<jupyter_output>Words: ['слово1', 'слово2', 'слово3', 'слово4']
Get index: 2
All index: {'слово1': 0, 'слово2': 1, 'слово3': 2, 'слово4': 3}
Matrix: [[1 1 1 0]
 [0 1 1 0]
 [2 1 0 0]
 [0 0 0 1]]
New doc:
  (0, 0)	1
  (0, 3)	2
Matrix frequency: [3 3 2 1]
Final matrix:
[['слово1' 'слово2' 'слово3' 'слово4']
 ['3' '3' '2' '1']]<jupyter_text>Также отмечу, что необязательно оперировать именно словами: в некоторых случаях можно генерировать N-граммы из букв (например, такой алгоритм учтет сходство родственных слов или опечаток).<jupyter_code>from scipy.spatial.distance import euclidean
vect = CountVectorizer(ngram_range=(3,3), analyzer='char_wb') 

n1, n2, n3, n4, n5 = vect.fit_transform(
    ['иванов', 'петров', 'петренко', 'смит', 'азамат']).toarray()

print(euclidean(n1, n2))  # Евклидово растояние 
print(euclidean(n2, n3))
print(euclidean(n3, n4))
print(euclidean(n3, n5))

vect.vocabulary_<jupyter_output>3.1622776601683795
2.8284271247461903
3.4641016151377544
3.7416573867739413<jupyter_text>Часто для задач, связанных с картинками, используется какая-нибудь сверточная сеть. Можно не придумывать архитектуру и не обучать сеть с нуля, а взять предобученную state of the art сеть, веса которой можно скачать из открытых источников. Чтобы адаптировать ее под свою задачу, дата сайнтисты практикуют т.н. fine tuning: последние полносвязные слои сети "отрываются", вместо них добавляются новые, подобранные под конкретную задачу, и сеть дообучается на новых данных. Но если вы хотите просто векторизовать изображение для каких-то своих целей (например, использовать какой-то несетевой классификатор) – просто оторвите последние слои и используйте выход предыдущих слоев:<jupyter_code>from keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from scipy.misc import face
import numpy as np
import matplotlib.pyplot as plt

f, ax = plt.subplots(nrows=2, ncols=1)
ax[0].axis('off')
ax[1].axis('off')

print(face().shape)
img = image.array_to_img(face())
ax[0].imshow(img)
img = img.resize((224, 224))
ax[1].imshow(img)
x = image.img_to_array(img)
print(x.shape)
x = np.expand_dims(x, axis=0)
print(x.shape)
resnet_settings = {'include_top': False, 'weights': 'imagenet'}
resnet = ResNet50(**resnet_settings)

img = image.array_to_img(face())
# какой милый енот! 
img = img.resize((224, 224))
# в реальной жизни может понадобиться внимательнее относиться к ресайзу
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
# нужно дополнительное измерение, т.к. модель рассчитана на работу с массивом изображений

features = resnet.predict(x)  # не очень понял чего это<jupyter_output>WARNING:tensorflow:From /home/worker/anaconda3/lib/python3.7/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.<jupyter_text>Прочитать текст на картинке.<jupyter_code>import pytesseract
from PIL import Image
import requests
from io import BytesIO

# In : img = 'http://ohscurrent.org/wp-content/uploads/2015/09/domus-01-google.jpg'
# просто случайная картинка из поиска 
# img = requests.get(img)
with Image.open('./data/1.png') as im:
    #     img = Image.open(BytesIO(img.content))
    text = pytesseract.image_to_string(img)
    text<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.126809937509526, 'fraction_numerical': 0.03642737387593355, 'mean_word_length': 4.776408450704225, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '194408', 'license': 'MIT', 'n_tokens_mistral': 2739, 'n_tokens_neox': 2864, 'n_words': 655, 'path': 'ods.ipynb', 'repo_name': 'Factotum8/feature_selection_examples', 'size': '6561'}