[PYTHON] 100 coups de traitement du langage amateur: 78

C'est un record de défi de 100 langues de traitement knock 2015. L'environnement est Ubuntu 16.04 LTS + Python 3.5.2 : : Anaconda 4.1.1 (64 bits). Cliquez ici pour une liste des coups passés (http://qiita.com/segavvy/items/fb50ba8097d59475f760).

Chapitre 8: Apprentissage automatique

Dans ce chapitre, la tâche de classer les phrases en positives (positives) ou négatives (négatives) à l'aide du jeu de données de polarité des phrases v1.0 de Movie Review Data publié par Bo Pang et Lillian Lee (analyse de polarité). Travailler sur.

Test croisé de division 78,5

Dans l'expérience> 76-77, le cas utilisé pour l'apprentissage a également été utilisé pour l'évaluation, il ne peut donc pas être considéré comme une évaluation valide. Autrement dit, le classificateur évalue les performances lors de la mémorisation du cas de formation et ne mesure pas les performances de généralisation du modèle. Par conséquent, trouvez le taux de réponse, le taux de précision, le taux de rappel et le score F1 corrects de la classification de polarité par le test croisé à 5 divisions.

Le code fini:

main.py


# coding: utf-8
import codecs
import snowballstemmer
import numpy as np

fname_sentiment = 'sentiment.txt'
fname_features = 'features.txt'
fname_result = 'result.txt'
fencoding = 'cp1252'		# Windows-1252 semble

division = 5			#Nombre de divisions de données
learn_alpha = 6.0		#Taux d'apprentissage
learn_count = 1000		#Nombre d'itérations d'apprentissage

stemmer = snowballstemmer.stemmer('english')

#Liste des mots vides http://xpo6.com/list-of-english-stop-words/À partir du format CSV
stop_words = (
	'a,able,about,across,after,all,almost,also,am,among,an,and,any,are,'
	'as,at,be,because,been,but,by,can,cannot,could,dear,did,do,does,'
	'either,else,ever,every,for,from,get,got,had,has,have,he,her,hers,'
	'him,his,how,however,i,if,in,into,is,it,its,just,least,let,like,'
	'likely,may,me,might,most,must,my,neither,no,nor,not,of,off,often,'
	'on,only,or,other,our,own,rather,said,say,says,she,should,since,so,'
	'some,than,that,the,their,them,then,there,these,they,this,tis,to,too,'
	'twas,us,wants,was,we,were,what,when,where,which,while,who,whom,why,'
	'will,with,would,yet,you,your').lower().split(',')


def is_stopword(str):
	'''Renvoie si le caractère est un mot vide
Égaliser le cas

Valeur de retour:
Vrai pour les mots vides, Faux pour différents
	'''
	return str.lower() in stop_words


def hypothesis(data_x, theta):
	'''Fonction hypothétique
	data_Pour x, utilisez thêta pour les données_Prédire y

Valeur de retour:
Matrice de valeurs prédites
	'''
	return 1.0 / (1.0 + np.exp(-data_x.dot(theta)))


def cost(data_x, theta, data_y):
	'''Fonction objective
	data_Calculez la différence entre le résultat prédit et la bonne réponse pour x

Valeur de retour:
Différence entre prédiction et réponse correcte
	'''
	m = data_y.size			#Nombre de données
	h = hypothesis(data_x, theta)		# data_Matrice de valeurs prédites de y
	j = 1 / m * np.sum(-data_y * np.log(h) -
			(np.ones(m) - data_y) * np.log(np.ones(m) - h))

	return j


def gradient(data_x, theta, data_y):
	'''Calcul de la pente à la descente la plus raide

Valeur de retour:
Matrice de dégradé pour thêta
	'''
	m = data_y.size			#Nombre de données
	h = hypothesis(data_x, theta)		# data_Matrice de valeurs prédites de y
	grad = 1 / m * (h - data_y).dot(data_x)

	return grad


def extract_features(data, dict_features):
	'''Extraire l'identité du texte
Dict du texte_Extraire les fonctionnalités incluses dans les fonctionnalités et
	dict_features['(Identité)']Renvoie une matrice avec la position 1.
Le premier élément est fixé à 1. Pour des poids qui ne correspondent pas à la nature.

Valeur de retour:
Le premier élément et la position de l'élément correspondant+Matrice avec 1 comme 1
	'''
	data_one_x = np.zeros(len(dict_features) + 1, dtype=np.float64)
	data_one_x[0] = 1		#Le premier élément est fixe et 1 pour les poids qui ne correspondent pas à la nature.

	for word in data.split(' '):

		#Supprimer les caractères vides avant et après
		word = word.strip()

		#Arrêter la suppression des mots
		if is_stopword(word):
			continue

		#Tige
		word = stemmer.stemWord(word)

		#Obtenez l'indice d'identité, définissez la partie correspondante de la matrice sur 1
		try:
			data_one_x[dict_features[word]] = 1
		except:
			pass		# dict_Ignorer les fonctionnalités introuvables dans les fonctionnalités

	return data_one_x


def load_dict_features():
	'''features.Lire txt et créer un dictionnaire pour convertir l'identité en index
La valeur de l'index est basée sur 1, caractéristiques.Correspond au numéro de ligne en txt.

Valeur de retour:
Un dictionnaire qui convertit les identités en index
	'''
	with codecs.open(fname_features, 'r', fencoding) as file_in:
		return {line.strip(): i for i, line in enumerate(file_in, start=1)}


def create_training_set(sentiments, dict_features):
	'''Créer une matrice à apprendre et une matrice avec des étiquettes polaires à partir des bons sentiments de données de réponse
La taille de l'exemple de ligne à apprendre est le nombre de révisions des bonnes réponses ×(Numéro élémentaire+1)。
La valeur de la colonne sera 1 s'il existe une prédisposition appropriée pour chaque revue, et 0 sinon.
L'index de l'identité de la colonne est dict_features['(Identité)']C'est décidé par.
La première colonne est toujours 1 pour l'apprentissage des poids qui ne correspondent pas à la nature.
	dict_Ignorez les fonctionnalités qui n'existent pas dans les fonctionnalités.

La taille de la matrice des étiquettes polaires est le nombre d'avis x 1.
1 pour un contenu positif et 0 pour un contenu négatif.

Valeur de retour:
Matrice à apprendre,Matrice d'étiquettes polaires
	'''

	#Initialiser la matrice avec 0
	data_x = np.zeros([len(sentiments), len(dict_features) + 1], dtype=np.float64)
	data_y = np.zeros(len(sentiments), dtype=np.float64)

	for i, line in enumerate(sentiments):

		#Extraction d'identité
		data_x[i] = extract_features(line[3:], dict_features)

		#Ensemble de matrices d'étiquettes polaires
		if line[0:2] == '+1':
			data_y[i] = 1

	return data_x, data_y


def learn(data_x, data_y, alpha, count):
	'''Apprentissage de la régression logistique

Valeur de retour:
Thêta formé
	'''
	theta = np.zeros(data_x.shape[1])
	c = cost(data_x, theta, data_y)
	print('\t Commencez à apprendre\tcost:{}'.format(c))

	for i in range(1, count + 1):

		grad = gradient(data_x, theta, data_y)
		theta -= alpha * grad

		#Calculez le coût et le montant maximum d'ajustement de thêta et affichez la progression (une fois toutes les 100 fois)
		if i % 100 == 0:
			c = cost(data_x, theta, data_y)
			e = np.max(np.absolute(alpha * grad))
			print('\t apprendre(#{})\tcost:{}\tE:{}'.format(i, c, e))

	c = cost(data_x, theta, data_y)
	e = np.max(np.absolute(alpha * grad))
	print('\t Apprentissage terminé(#{}) \tcost:{}\tE:{}'.format(i, c, e))
	return theta


def score(fname):
	'''Calcul du score à partir du fichier de résultats
Lit le fichier de résultats spécifié par fname et renvoie le taux de réponse, le taux de précision, le taux de rappel et le score F1 corrects.

Valeur de retour:
Taux de réponse correct,Taux de conformité,Rappel,Score F1
	'''
	#Lire les résultats et agréger
	TP = 0		# True-Attentes positives+1, bonne réponse+1
	FP = 0		# False-Attentes positives+1, la bonne réponse est-1
	FN = 0		# False-Attentes négatives-1, la bonne réponse est+1
	TN = 0		# True-Attentes négatives-1, bonne réponse-1

	with open(fname) as data_file:
		for line in data_file:
			cols = line.split('\t')

			if len(cols) < 3:
				continue

			if cols[0] == '+1':			#Bonne réponse
				if cols[1] == '+1':		#Attendu
					TP += 1
				else:
					FN += 1
			else:
				if cols[1] == '+1':
					FP += 1
				else:
					TN += 1

	#Calcul
	accuracy = (TP + TN) / (TP + FP + FN + TN)		#Taux de réponse correct
	precision = TP / (TP + FP)		#Taux de conformité
	recall = TP / (TP + FN)		#Rappel
	f1 = (2 * recall * precision) / (recall + precision) 	#Score F1

	return accuracy, precision, recall, f1


#Lire le dictionnaire d'identité
dict_features = load_dict_features()

#Lire les bonnes réponses
with codecs.open(fname_sentiment, 'r', fencoding) as file_in:
	sentiments_all = list(file_in)

#Divisez les bonnes réponses en 5
sentiments = []
unit = int(len(sentiments_all) / division)
for i in range(5):
	sentiments.append(sentiments_all[i * unit:(i + 1) * unit])

#Test croisé en 5 divisions
with open(fname_result, 'w') as file_out:
	for i in range(division):

		print('{}/{}'.format(i + 1, division))

		#Divisez les bonnes réponses pour l'apprentissage et la vérification
		data_learn = []
		for j in range(division):
			if i == j:
				data_validation = sentiments[j]
			else:
				data_learn += sentiments[j]

		#Création d'un éventail de cibles d'apprentissage et d'étiquettes polaires
		data_x, data_y = create_training_set(data_learn, dict_features)

		#Apprentissage
		theta = learn(data_x, data_y, alpha=learn_alpha, count=learn_count)

		#Vérification
		for line in data_validation:

			#Extraction d'identité
			data_one_x = extract_features(line[3:], dict_features)

			#Prédiction, sortie des résultats
			h = hypothesis(data_one_x, theta)
			if h > 0.5:
				file_out.write('{}\t{}\t{}\n'.format(line[0:2], '+1', h))
			else:
				file_out.write('{}\t{}\t{}\n'.format(line[0:2], '-1', 1 - h))

#Affichage des résultats
print('\n Taux d'apprentissage:{}\t Nombre de répétitions d'apprentissage:{}'.format(learn_alpha, learn_count))
accuracy, precision, recall, f1 = score(fname_result)
print('Taux de réponse correct\t{}\n Taux de conformité\t{}\n rappel\t{}\score nF1\t{}'.format(
	accuracy, precision, recall, f1
))

Résultat de l'exécution:

Résultat d'exécution


1/5
Coût de l'apprentissage: 0.6931471805599453
Apprentissage(#100)	cost:0.46843942718055814	E:0.006388382573910524
Apprentissage(#200)	cost:0.4155300488897057	E:0.003950176267083882
Apprentissage(#300)	cost:0.3855283848183693	E:0.002867235531957132
Apprentissage(#400)	cost:0.3648933651792237	E:0.0022495471367582247
Apprentissage(#500)	cost:0.3493282931816998	E:0.0018583498524543404
Apprentissage(#600)	cost:0.3369232080431452	E:0.0016771358183603987
Apprentissage(#700)	cost:0.32666634898652896	E:0.001528412108716516
Apprentissage(#800)	cost:0.31795919554061053	E:0.0014042508127869423
Apprentissage(#900)	cost:0.31041943220497686	E:0.0012990594970099315
Apprentissage(#1000)	cost:0.30378857681325766	E:0.0012088047599478039
Apprentissage terminé(#1000) 	cost:0.30378857681325766	E:0.0012088047599478039
2/5
Coût de l'apprentissage: 0.6931471805599453
Apprentissage(#100)	cost:0.4741687433335998	E:0.006589814822192543
Apprentissage(#200)	cost:0.42144780985764596	E:0.003908261118677938
Apprentissage(#300)	cost:0.3912183151335336	E:0.002804459291483359
Apprentissage(#400)	cost:0.370303379815077	E:0.0023610369221010326
Apprentissage(#500)	cost:0.354477846021314	E:0.0020514997491309413
Apprentissage(#600)	cost:0.3418460542105294	E:0.0018224684562050484
Apprentissage(#700)	cost:0.33139550986560584	E:0.001645643112098399
Apprentissage(#800)	cost:0.3225230456812948	E:0.0015047097369745835
Apprentissage(#900)	cost:0.31484124228803834	E:0.0013896119787524179
Apprentissage(#1000)	cost:0.3080871067835467	E:0.0012937962132790058
Apprentissage terminé(#1000) 	cost:0.3080871067835467	E:0.0012937962132790058
3/5
Coût de l'apprentissage: 0.6931471805599453
Apprentissage(#100)	cost:0.46891949543978517	E:0.006357216339527686
Apprentissage(#200)	cost:0.41580499264287696	E:0.003532830533162978
Apprentissage(#300)	cost:0.3854553165948075	E:0.0027301913427912735
Apprentissage(#400)	cost:0.3644760512004263	E:0.0022545615099526647
Apprentissage(#500)	cost:0.3485986820681382	E:0.001919021249806922
Apprentissage(#600)	cost:0.3359163761795678	E:0.0016705021198879075
Apprentissage(#700)	cost:0.32541428766128333	E:0.0014797071516709523
Apprentissage(#800)	cost:0.31648958311645375	E:0.0013367387334497819
Apprentissage(#900)	cost:0.3087557956043563	E:0.0012494627215075146
Apprentissage(#1000)	cost:0.3019508027016161	E:0.0011779206121903469
Apprentissage terminé(#1000) 	cost:0.3019508027016161	E:0.0011779206121903469
4/5
Coût de l'apprentissage: 0.6931471805599453
Apprentissage(#100)	cost:0.4725342546493931	E:0.006182597071964639
Apprentissage(#200)	cost:0.4194276723005623	E:0.0034649497530972943
Apprentissage(#300)	cost:0.38918298242842136	E:0.0025501444797361994
Apprentissage(#400)	cost:0.36832204557828535	E:0.0021388621069763788
Apprentissage(#500)	cost:0.3525543611131982	E:0.001855410065711756
Apprentissage(#600)	cost:0.33996964450743344	E:0.0016480855756071824
Apprentissage(#700)	cost:0.32955351095109425	E:0.0014898405345723522
Apprentissage(#800)	cost:0.32070420313966275	E:0.001365069555771408
Apprentissage(#900)	cost:0.3130363527272276	E:0.0012842751555114352
Apprentissage(#1000)	cost:0.3062888953703655	E:0.0012201511930926112
Apprentissage terminé(#1000) 	cost:0.3062888953703655	E:0.0012201511930926112
5/5
Coût de l'apprentissage: 0.6931471805599453
Apprentissage(#100)	cost:0.47367883038307196	E:0.006165844710913304
Apprentissage(#200)	cost:0.42196370471708444	E:0.0038294500786362744
Apprentissage(#300)	cost:0.39242868456409186	E:0.002903639748114128
Apprentissage(#400)	cost:0.3720216436950633	E:0.002348459481805761
Apprentissage(#500)	cost:0.3565815749862366	E:0.0019763223680587666
Apprentissage(#600)	cost:0.34425094991837796	E:0.001708469854933442
Apprentissage(#700)	cost:0.33404185010109005	E:0.0015059837001246833
Apprentissage(#800)	cost:0.32536765342218166	E:0.001357007404701798
Apprentissage(#900)	cost:0.3178523514158344	E:0.0012612117027114012
Apprentissage(#1000)	cost:0.3112409530842421	E:0.0011798784899874886
Apprentissage terminé(#1000) 	cost:0.3112409530842421	E:0.0011798784899874886

Taux d'apprentissage: 6.0 Nombre de répétitions d'apprentissage: 1000
Taux de réponse correct 0.7483114446529081
Taux de conformité 0.749058734939759
Taux de rappel 0.7466691686995685
Score F1 0.7478620430410676

Qu'est-ce qu'un test croisé?

Lors de la vérification de l'exactitude des résultats d'entraînement, même si les données utilisées pour l'entraînement sont utilisées pour la vérification, l'exactitude des données inconnues ne peut pas être déterminée. En outre, la vérification avec les données utilisées pour l'apprentissage donnera de bons résultats même dans l'apprentissage (appelé surapprentissage) qui ne peut pas être appliqué dans la mémorisation dite des manuels. Par conséquent, il est nécessaire de vérifier avec les données qui ne sont pas utilisées pour la formation. C'est ce qu'on appelle un test croisé.

Il semble y avoir des méthodes courantes de test croisé. Le "test d'intersection de division en K" spécifié dans cette question est une méthode de division des données en K et d'utilisation de l'un d'entre eux pour la vérification et le reste pour l'apprentissage. Ceci est répété K fois tout en commutant les données de vérification et en moyenne. Les détails sont publiés sur "gihyo.jp" de Technical Review Co., Ltd. 21e (final) Commençons l'apprentissage automatique ) Est facile à comprendre.

De plus, dans l'exemple [Machine Learning] de Coursera (https://www.coursera.org/learn/machine-learning), une autre méthode a été recommandée. Il s'agit d'une méthode de division en trois parties, les données d'entraînement, les données d'ajustement et les données de vérification, l'apprentissage avec les données d'entraînement, l'ajustement avec les données d'ajustement et enfin la confirmation de l'exactitude du résultat avec les données de vérification. Pour plus d'informations, voir [Coursera Machine Learning (6): Machine Learning Model Evaluation (Cross Test, Bias & Variance, Conformance & Reproductibility)] de katsu1110 (http://qiita.com/katsu1110/items/97c3f98a987ea92b2cc1) Le résumé est facile à comprendre.

Mise en œuvre d'un test d'intersection en 5 parties

J'ai simplement divisé les données en 5 parties et je les ai mises en œuvre. Puisqu'il y a 10 662 données au total, j'ai décidé que les 2 cas restants qui n'ont pas cassé n'étaient pas gênants à gérer ^^;

Notez que toutes les fonctions ont été créées à partir des problèmes précédents. Concernant le calcul du score, pour utiliser le score () créé dans Problème 77 tel quel, le résultat de le prédire en 5 fois est [Problème] 76](http://qiita.com/segavvy/items/e107f764534f01c5b105) J'ai ajouté à un fichier et créé un gros fichier de résultats à manger par score () ..

À propos de l'amélioration de la précision

Malheureusement, il est tombé à un peu moins de 75%. Cela semble un peu bas, mais je vais passer au problème suivant pour le moment.

Afin d'améliorer la précision, il y a diverses choses telles que l'augmentation de la nature, l'augmentation des données, l'ajout de paramètres de normalisation, l'augmentation du polynôme de la fonction hypothétique, la révision de la méthode d'extraction de la nature, etc. Il y a un moyen. Cependant, même si vous essayez diverses choses avec vos propres idées, cela ne fait que perdre du temps et il semble que la précision ne puisse pas être améliorée facilement.

Dans [Machine Learning] de Coursera (https://www.coursera.org/learn/machine-learning), la première cause d'inexactitudes pour l'amélioration est le surapprentissage (trop dépendant des données d'entraînement, variance élevée). Il a été dit qu'il fallait déterminer s'il était sous-ajusté (biais élevé, qui n'utilise pas pleinement les données d'entraînement). Cela peut être déterminé en introduisant un paramètre normalisé. Le résultat déterminera la démarche d'amélioration. Vous pouvez en apprendre davantage sur la vérification et l'amélioration à la semaine 6 de Machine Learning.

C'est tout pour le 79e coup. Si vous avez des erreurs, je vous serais reconnaissant de bien vouloir les signaler.


Recommended Posts

100 coups de traitement du langage amateur: 41
100 coups de traitement du langage amateur: 71
100 coups de traitement du langage amateur: 56
100 coups de traitement du langage amateur: 24
100 coups de traitement du langage amateur: 59
100 coups de traitement du langage amateur: 70
100 coups de traitement du langage amateur: 60
100 coups de traitement du langage amateur: 92
100 coups de langue amateur: 30
100 coups de langue amateur: 06
100 coups de traitement du langage amateur: 84
100 coups de traitement du langage amateur: 81
100 coups de langue amateur: 33
100 coups de traitement du langage amateur: 40
100 coups de traitement du langage amateur: 45
100 coups de traitement du langage amateur: 43
100 coups de traitement du langage amateur: 55
100 coups de traitement du langage amateur: 22
100 coups de traitement du langage amateur: 61
100 coups de traitement du langage amateur: 94
100 coups de traitement du langage amateur: 54
100 coups de langue amateur: 04
100 coups de traitement du langage amateur: 63
100 coups de traitement du langage amateur: 78
100 coups de traitement du langage amateur: 12
100 coups de traitement du langage amateur: 14
100 coups de langue amateur: 08
100 coups de traitement du langage amateur: 42
100 coups de traitement du langage amateur: 19
100 coups de traitement du langage amateur: 73
100 coups de traitement du langage amateur: 75
100 coups de traitement du langage amateur: 98
100 coups de traitement du langage amateur: 83
100 coups de traitement du langage amateur: 95
100 coups de traitement du langage amateur: 32
100 coups de traitement du langage amateur: 96
100 coups de traitement du langage amateur: 87
100 coups de traitement du langage amateur: 72
100 coups de traitement du langage amateur: 79
100 coups de traitement du langage amateur: 23
100 coups de langue amateur: 05
100 coups de langue amateur: 00
100 coups de langue amateur: 02
100 coups de traitement du langage amateur: 37
100 coups de traitement du langage amateur: 21
100 coups de traitement du langage amateur: 68
100 coups de traitement du langage amateur: 11
100 coups de traitement du langage amateur: 90
100 coups de traitement du langage amateur: 74
100 coups de traitement du langage amateur: 66
100 coups de traitement du langage amateur: 28
100 coups de traitement du langage amateur: 64
100 coups de traitement du langage amateur: 34
100 coups de traitement du langage amateur: 36
100 coups de traitement du langage amateur: 77
100 coups de langue amateur: 01
100 coups de traitement du langage amateur: 16
100 coups de traitement du langage amateur: 27
100 coups de traitement du langage amateur: 10
100 coups de traitement du langage amateur: 03
100 coups de traitement du langage amateur: 82