мне необходимо произвести “канонизацию” текста для кластеризации. Новостные сообщения берутся из базы данных SqlServer. Во время проверки слов в стоп-словаре они перекодируются из unicode в СP1251.
bad= {u'\u2500', u'\xb8'} text = [x for x in [y.strip(stop_symbols) for y in source.lower().split()]if x and x not in bad and (x.encode('cp1251') not in stop_words)]
UnicodeEncodeError: ‘charmap’ codec can't encode character u'\xb8' in position 9: character maps to <undefined>
в процессе поиска решения в интернете узнал, что ошибки связаны с так называемыми “кракозяблями” появляющиеся из кодировки CP1252. Тогда я создал словарь bad, чтоб эти слова не проверял в словаре, т.о. я избавился от ошибки
UnicodeEncodeError: ‘charmap’ codec can't encode character u'\u2500' in position 0: character maps to <undefined>
хочу обратить внимание на “position 0”. С такой позицией больше ошибки не появлялись, а вот с ошибкой в 9 позиции разобраться не могу.
спасибо за ответ заранее
весь код представлен ниже:
# using: utf-8 import numpy import scipy from scipy import linalg import nltk import Stemmer stemmer = Stemmer.Stemmer('russian') import cmath import numpy as np import matplotlib.pyplot as plt from scipy.cluster import hierarchy from scipy.cluster import * from collections import deque import pyodbc import hashlib import binascii if __name__ == '__build__': raise Exception """функция канонизации текста, приводит буквы к нижнему регистр, удаляются стоп-слова и происхолит стиммирование""" def canonize(source): stop_symbols = ''''.,!?:;-\'\|/<>~$^&*(){}"''' stop_words = ('это', 'как', 'так','[1]','[2]','[3]','[4]','[5]','[6]','[7]','[8]','[9]', 'и', 'в', 'над','без','более','больше','будет','будто','бы','был','была','было','были','вам','вас','вдруг','наконец','нас','со','совсем','нельзя', 'к', 'до', 'не','ведь','вот','впрочем','все','всегда','всего','всех','всю','вы','где','говорил','да', 'нет','ни','нибудь','ним','них','ну', 'на', 'но', 'за','даже','два','другой','его','еще','ее','ей','ему','если','есть','нее','него','за','зачем','здесь','из-за','или','он','она', 'то', 'с', 'ли','им','иногда','их','кажется','как','когда','конечно','которые','куда','лучше','между','меня','мне','мой','моя','мы','над','надо', 'а', 'во', 'от','опять','от','конечно','перед','по','под','после','потом','потому','почти','при','про','раз','разве','сам','свое','свои','себе', 'со', 'для', 'о','себя','наконец','сегодня','сейчас','сказал','сказала','сказать','совсем','так','такой','там','тебя','тем','теперь','то','тогда', 'же', 'ну', 'вы', 'того','тоже','только','том','тот','три','тут','ты','у','уж','уже','хорошо','хоть','чего','человек','чем','через','что','чтоб', 'бы', 'что', 'кто','чтобы','чуть','эти','этого','этой','этом','этот','эту','я','он', 'она','из','не') bad= {u'\u2500', u'\xb8'} text = [x for x in [y.strip(stop_symbols) for y in source.lower().split()]if x and x not in bad and (x.encode('cp1251') not in stop_words)] for i in range(len(text)): if type(text[i]) == unicode: text[i] = text[i].encode('utf-8') text[i] = text[i].decode('utf-8') text[i] = stemmer.stemWord(text[i]) text[i] = text[i].encode('cp1251') return ( text ) """функцию, которая производит разбиение текста на шинглы, где shingleLen- длина шинглов . На выходе хеш-функции шинглов""" def genshingle(source,shingleLen): out = [] for i in range(len(source)-(shingleLen-1)): out.append (binascii.crc32(' '.join( [x for x in source[i:i+shingleLen]]))) return out """ функция находит пересечения шинглов 2х текстов""" def compaire (source1,source2): same = 0 for i in range(len(source1)): if source1[i] in source2: same = same + 1 return same*2/float(len(source1) + len(source2)) """ функция получает массив метрик близости текстов, необходимый для кластеризации, где к - длина шинглов""" def shingle_dist(texts,k): dist=[] for i in range(len(texts)-1): text1 = canonize(texts[i]) shingle1 = genshingle(text1,k) for j in range(len(texts)-i-1): text2 = canonize(texts[i+j+1]) shingle2 = genshingle(text2,k) dist.append(1-compaire (shingle1,shingle2)) return dist docs=[] cnxn = pyodbc.connect('Trusted_Connection=yes', DRIVER='{SQL Server}',SERVER= '127.0.0.1' ,DATABASE= 'TASTODb1', UID= 'sa', PWD= '1qaz@WSX') cursor = cnxn.cursor() cursor.execute(""" select text from texts where (id < 178) and (id > 175)""") for row in cursor: docs.append(row.text) f=open('text1.txt','w') f.close() dist = shingle_dist(docs,2) Z = hierarchy.linkage( dist, method='average') print Z