In [1]:
import matplotlib.pyplot as plt
import numpy as np
import scipy
import sklearn as sk

%matplotlib inline

CountVectorizer

...compte le nombre d'instances de mots. La représentation dense nous montre le vecteur de critères correspondant à chaque phrase dans corpus. Sinon, la représentation est creuse.

Essaiez avec le corpus entier pour voir ce que donne un document plus important.

À essayer et expliquer :

  • corpus_encoded.shape
  • corpus_encoded[0].todense()
  • corpus_encoded[0].data et print(corpus_encoded[0]).
  • corpus_encoded.todense()[0]
  • vectorizer.inverse_transform(corpus_encoded.todense()[0])
  • vectorizer.transform('The dog runs quickly towards the cat.')
  • vectorizer.transform(['The dog runs quickly towards the cat.'])
  • vectorizer2 = CountVectorizer(binary=True)

In [2]:
from sklearn.feature_extraction.text import CountVectorizer

corpus = [
    "Il est nuit. La cabane est pauvre, mais bien close.",
    "Le logis est plein d'ombre et l'on sent quelque chose",
    "Qui rayonne à travers ce crépuscule obscur.",
    "Des filets de pêcheur sont accrochés au mur.",
    "Au fond, dans l'encoignure où quelque humble vaisselle",
    "Aux planches d'un bahut vaguement étincelle,",
    "On distingue un grand lit aux longs rideaux tombants.",
    "Tout près, un matelas s'étend sur de vieux bancs,",
    "Et cinq petits enfants, nid d'âmes, y sommeillent",
    "La haute cheminée où quelques flammes veillent",
    "Rougit le plafond sombre, et, le front sur le lit,",
    "Une femme à genoux prie, et songe, et pâlit.",
    "C'est la mère. Elle est seule. Et dehors, blanc d'écume,",
    "Au ciel, aux vents, aux rocs, à la nuit, à la brume,",
    "Le sinistre océan jette son noir sanglot.",
]
corpus2 = corpus[0:2]
vectorizer = CountVectorizer()
corpus_encoded = vectorizer.fit_transform(corpus2)
print(corpus_encoded.todense())
print('----------------------------------------------------------------')
print(vectorizer.vocabulary_)


[[1 1 0 1 2 0 1 1 0 0 1 1 0 0 1 0 0 0]
 [0 0 1 0 1 1 0 0 1 1 0 0 1 1 0 1 1 1]]
----------------------------------------------------------------
{u'chose': 2, u'nuit': 11, u'quelque': 16, u'il': 6, u'close': 3, u'et': 5, u'pauvre': 14, u'on': 13, u'est': 4, u'plein': 15, u'mais': 10, u'la': 7, u'cabane': 1, u'logis': 9, u'le': 8, u'bien': 0, u'ombre': 12, u'sent': 17}

Mots vides

Ceci ne marche pas :

vectorizer2 = CountVectorizer(stop_words='francais')

Découvrez un peu plus. (Astuce : qu'est-ce qui est l'erreur si vous appelez fit_transform()?)

Distance

  • Les vecteurs et matrices sont creuse. Pourquoi?
  • Quel problème aurons-nous avec la distance euclidienne?

In [3]:
from sklearn.metrics.pairwise import euclidean_distances

print(euclidean_distances(corpus_encoded[0], corpus_encoded[1]))
print(euclidean_distances(corpus_encoded[0], corpus_encoded[0]))
jour = vectorizer.transform(['Il est jour. La cabane est pauvre, mais bien close.'])
print(euclidean_distances(corpus_encoded[0], jour))


[[ 4.24264069]]
[[ 0.]]
[[ 1.]]

TF-IDF


In [4]:
from sklearn.feature_extraction.text import TfidfVectorizer

tfidf_vectorizer = TfidfVectorizer()
print(corpus2[0])
print(corpus2[1])
print(tfidf_vectorizer.fit_transform(corpus2).todense())
print('--------------------------------------------------------------')
print(vectorizer.fit_transform(corpus2).todense())


Il est nuit. La cabane est pauvre, mais bien close.
Le logis est plein d'ombre et l'on sent quelque chose
[[ 0.3158336   0.3158336   0.          0.3158336   0.44943642  0.
   0.3158336   0.3158336   0.          0.          0.3158336   0.3158336
   0.          0.          0.3158336   0.          0.          0.        ]
 [ 0.          0.          0.32433627  0.          0.23076793  0.32433627
   0.          0.          0.32433627  0.32433627  0.          0.
   0.32433627  0.32433627  0.          0.32433627  0.32433627  0.32433627]]
--------------------------------------------------------------
[[1 1 0 1 2 0 1 1 0 0 1 1 0 0 1 0 0 0]
 [0 0 1 0 1 1 0 0 1 1 0 0 1 1 0 1 1 1]]

HashingVectorizer()

  • Pourquoi disons-nous transform([corpus0]) au lieu de transform(corpus0)?
  • Expliquez l'option norm
  • Pourquoi n_features=6? Et si on essaie n_features=10? n_features=50?

In [5]:
from sklearn.feature_extraction.text import HashingVectorizer

hash_vectorizer = HashingVectorizer(n_features=6, norm=None)
corpus1 = corpus[:1]
print(corpus1)
print(hash_vectorizer.transform(corpus1).todense())
# Trouvons les indexes non-zéro.
scipy.sparse.find(hash_vectorizer.transform(corpus1))


['Il est nuit. La cabane est pauvre, mais bien close.']
[[ 0. -3.  2. -1.  1. -1.]]
Out[5]:
(array([0, 0, 0, 0, 0], dtype=int32),
 array([1, 2, 3, 4, 5], dtype=int32),
 array([-3.,  2., -1.,  1., -1.]))

Computer Vision

ROC : reconnaissance optique de caractères

(OCR : optical characater recognition)


In [6]:
from sklearn import datasets

digits = datasets.load_digits()
print('Digit:', digits.target[0])
print(digits.images[0])
print('Feature vector:\n', digits.images[0].reshape(-1, 64))

plt.figure(1, figsize=(3, 3))
plt.imshow(digits.images[-1], cmap=plt.cm.gray_r, interpolation='nearest')
plt.show()


('Digit:', 0)
[[  0.   0.   5.  13.   9.   1.   0.   0.]
 [  0.   0.  13.  15.  10.  15.   5.   0.]
 [  0.   3.  15.   2.   0.  11.   8.   0.]
 [  0.   4.  12.   0.   0.   8.   8.   0.]
 [  0.   5.   8.   0.   0.   9.   8.   0.]
 [  0.   4.  11.   0.   1.  12.   7.   0.]
 [  0.   2.  14.   5.  10.  12.   0.   0.]
 [  0.   0.   6.  13.  10.   0.   0.   0.]]
('Feature vector:\n', array([[  0.,   0.,   5.,  13.,   9.,   1.,   0.,   0.,   0.,   0.,  13.,
         15.,  10.,  15.,   5.,   0.,   0.,   3.,  15.,   2.,   0.,  11.,
          8.,   0.,   0.,   4.,  12.,   0.,   0.,   8.,   8.,   0.,   0.,
          5.,   8.,   0.,   0.,   9.,   8.,   0.,   0.,   4.,  11.,   0.,
          1.,  12.,   7.,   0.,   0.,   2.,  14.,   5.,  10.,  12.,   0.,
          0.,   0.,   0.,   6.,  13.,  10.,   0.,   0.,   0.]]))

Tout en même temps

Ici nous prenons un exemple de sklearn. Nous chargeons toutes les images du dataset digits, nous construisons un classifieur SVM (à venir, pour l'instant, c'est juste un classifieur), et nous apprenons comment classifier les chiffres sur la première moitié des données. Puis nous testons notre classifieur avec la deuxième moitié, où nous savons toujours le target (vérité, ground truth).

  • Étudiez (et executez) l'exemple. Comprenez tout ce que vous pouvez. Puis nous allons le discuter ensemble.

In [12]:
# Author: Gael Varoquaux <gael dot varoquaux at normalesup dot org>
# License: BSD 3 clause

# Standard scientific Python imports
import matplotlib.pyplot as plt
import math

# Import datasets, classifiers and performance metrics
from sklearn import datasets, svm, metrics

# The digits dataset
digits = datasets.load_digits()

# The data that we are interested in is made of 8x8 images of digits, let's
# have a look at the first 3 images, stored in the `images` attribute of the
# dataset.  If we were working from image files, we could load them using
# pylab.imread.  Note that each image must have the same size. For these
# images, we know which digit they represent: it is given in the 'target' of
# the dataset.
images_and_labels = list(zip(digits.images, digits.target))
for index, (image, label) in enumerate(images_and_labels[:4]):
    plt.subplot(2, 4, index + 1)
    plt.axis('off')
    plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')
    plt.title('Training: %i' % label)

# To apply a classifier on this data, we need to flatten the image, to
# turn the data in a (samples, feature) matrix:
n_samples = len(digits.images)
data = digits.images.reshape((n_samples, -1))

# Create a classifier: a support vector classifier
classifier = svm.SVC(gamma=0.001)

# We learn the digits on the first half of the digits
num_training = int(math.floor(n_samples / 2))
num_test = int(math.ceil(n_samples / 2))
classifier.fit(data[:num_training], digits.target[:num_training])

# Now predict the value of the digit on the second half:
expected = digits.target[num_test:]
predicted = classifier.predict(data[num_test:])

print("Classification report for classifier %s:\n%s\n"
      % (classifier, metrics.classification_report(expected, predicted)))
print("Confusion matrix:\n%s" % metrics.confusion_matrix(expected, predicted))

images_and_predictions = list(zip(digits.images[num_test:], predicted))
for index, (image, prediction) in enumerate(images_and_predictions[:4]):
    plt.subplot(2, 4, index + 5)
    plt.axis('off')
    plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')
    plt.title('Prediction: %i' % prediction)

plt.show()


Classification report for classifier SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma=0.001, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False):
             precision    recall  f1-score   support

          0       1.00      0.99      0.99        88
          1       0.99      0.97      0.98        91
          2       0.99      0.99      0.99        86
          3       0.98      0.87      0.92        91
          4       0.99      0.96      0.97        92
          5       0.95      0.97      0.96        91
          6       0.99      0.99      0.99        91
          7       0.96      0.99      0.97        89
          8       0.94      1.00      0.97        88
          9       0.93      0.98      0.95        92

avg / total       0.97      0.97      0.97       899


Confusion matrix:
[[87  0  0  0  1  0  0  0  0  0]
 [ 0 88  1  0  0  0  0  0  1  1]
 [ 0  0 85  1  0  0  0  0  0  0]
 [ 0  0  0 79  0  3  0  4  5  0]
 [ 0  0  0  0 88  0  0  0  0  4]
 [ 0  0  0  0  0 88  1  0  0  2]
 [ 0  1  0  0  0  0 90  0  0  0]
 [ 0  0  0  0  0  1  0 88  0  0]
 [ 0  0  0  0  0  0  0  0 88  0]
 [ 0  0  0  1  0  1  0  0  0 90]]

Feature extraction

Nous revenons aux techniques que nous comprenons. Commençons par la détection de contours.


In [8]:
from skimage.filters import roberts, sobel, scharr, prewitt
from skimage.color import rgb2gray
from skimage.data import camera
import skimage.io as io

# Au choix :
#image = camera()
image = rgb2gray(io.imread('victor.jpg'))
edge_roberts = roberts(image)
edge_sobel = sobel(image)

fig, (ax0, ax1) = plt.subplots(ncols=2)
ax0.imshow(edge_roberts, cmap=plt.cm.gray)
ax0.set_title('Roberts Edge Detection')
ax0.axis('off')
ax1.imshow(edge_sobel, cmap=plt.cm.gray)
ax1.set_title('Sobel Edge Detection')
ax1.axis('off')
plt.tight_layout()


Et maintenant procédons à la détection de coins (corners).


In [9]:
from skimage.feature import corner_harris, corner_peaks
from skimage.color import rgb2gray
from skimage.exposure import equalize_hist

def show_corners(corners, image):
    """Show corners on image."""
    fig = plt.figure()
    plt.gray()
    plt.imshow(image)
    y_corner, x_corner = zip(*corners)
    plt.plot(x_corner, y_corner, 'or')
    plt.xlim(0, image.shape[1])
    plt.ylim(image.shape[0], 0)
    fig.set_size_inches(np.array(fig.get_size_inches()) * 1.5)
    plt.show()

victor = io.imread('victor.jpg')
plt.imshow(victor)
victor = equalize_hist(rgb2gray(victor))
corners = corner_peaks(corner_harris(victor), min_distance=2)
show_corners(corners, victor)


SURF


In [10]:
import mahotas as mh
from mahotas.features import surf
image = mh.imread('victor.jpg', as_grey=True)
print('The first SURF descriptor:\n{img}'.format(img=surf.surf(image)[0]))
print('Extracted {num} SURF descriptors'.format(num=len(surf.surf(image))))


The first SURF descriptor:
[  1.73934920e+02   1.15739730e+02   6.82362215e+00   1.33172161e+03
  -1.00000000e+00  -1.72590177e+00  -1.73488596e-03   1.60767385e-03
   2.41392091e-03   2.54358196e-03  -4.63913959e-03   5.82528687e-03
   7.13811474e-03   2.46575102e-02  -3.49893813e-02   1.16461241e-02
   3.71493275e-02   3.64336913e-02  -4.36672949e-06  -2.62595375e-04
   3.47256345e-04   4.30159090e-04  -7.16022304e-03   4.10281861e-04
   9.80947097e-03   1.41317443e-02  -8.08527268e-02  -2.22776865e-02
   9.88504935e-02   1.33390201e-01  -1.70986336e-01   2.54923866e-01
   3.29441521e-01   3.02769588e-01  -2.29204426e-03  -8.20455264e-04
   3.18962218e-03   2.62901544e-03   2.87002299e-02   7.42304381e-03
   3.33238804e-02   1.08756279e-02   3.60754469e-01  -5.19080568e-02
   3.71979840e-01   1.16853960e-01   3.54340543e-01   1.53341738e-01
   4.36641395e-01   1.97137371e-01   2.69608672e-03  -1.46201405e-03
   1.14733040e-02   6.30267717e-03   1.02465197e-04  -1.21706419e-04
   1.70933243e-04   2.37069115e-04  -8.92483451e-04   5.86892356e-04
   3.41903045e-03   4.74388137e-03   1.95850762e-04  -5.98320672e-06
   3.66962631e-03   3.74011710e-03   1.01761910e-03  -1.05327434e-03
   1.27882875e-03   1.10225412e-03]
Extracted 646 SURF descriptors

In [ ]:


In [11]:
from sklearn import preprocessing

X = np.random.rand(4,4) * 100
print(X)
print('\n')
print(preprocessing.scale(X))


[[ 42.55591164  11.71356875  64.06726787  52.02482542]
 [ 24.82536892  97.70593262  84.97885712  46.06075797]
 [  2.54929088  57.80062942  61.6675414    3.76129804]
 [  2.42569486  32.65218421  63.80709224  33.43085436]]


[[ 1.45515509 -1.19436057 -0.48108116  0.97839966]
 [ 0.40063869  1.49044415  1.72368413  0.65787694]
 [-0.92422148  0.24454345 -0.7340908  -1.61539343]
 [-0.9315723  -0.54062702 -0.50851218 -0.02088316]]