Уведомления

Группа в Telegram: @pythonsu

#1 Март 15, 2015 12:28:31

boyusha
Зарегистрирован: 2014-05-04
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с "кракозябрами" при перекодировке

Доброго дня суток! столкнулся с проблемой и не могу ее решить, заключается она в следующем:
мне необходимо произвести “канонизацию” текста для кластеризации. Новостные сообщения берутся из базы данных 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

Офлайн

#2 Март 15, 2015 17:15:57

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Проблема с "кракозябрами" при перекодировке

1) что такое # using: utf-8
может

#-*- coding: utf-8 -*-
2) весь код эт хорошо, но мы не можем его запустить и проверить, а так сказать трудно
для решения подобных проблем ошибку нужно локализировать
вы должны оставить только ту функцию что выдает ошибку
предположем что эт
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 )
но мы не знаем что ей передается
запустите это код и напишите что он выдаст
#-*- coding: 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()
print docs
dist = shingle_dist(docs,2)
Z = hierarchy.linkage( dist, method='average')
print Z



————————————————
-*- Simple is better than complex -*-

Отредактировано terabayt (Март 15, 2015 17:16:43)

Офлайн

#3 Март 17, 2015 00:48:51

boyusha
Зарегистрирован: 2014-05-04
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с "кракозябрами" при перекодировке

проверил, ошибка осталась все та же…

Traceback (most recent call last):
  File "C:\Documents and Settings\Администратор\Рабочий стол\123.py", line 54, in <module>
    text.append(canonize(docs[i]))
  File "C:\Documents and Settings\Администратор\Рабочий стол\123.py", line 26, in canonize
    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)]
  File "C:\Python27\lib\encodings\cp1251.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\xb8' in position 9: character maps to <undefined>
для того, чтобы программа работала на Вашем компьютере, отсылаю файл с самой программой(где локализована ошибка), с текстами и с библиотекой.

Прикреплённый файлы:
attachment все необходимое для программы.7z (388,2 KБ)

Офлайн

#4 Март 17, 2015 00:49:16

boyusha
Зарегистрирован: 2014-05-04
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с "кракозябрами" при перекодировке

проверил, ошибка осталась все та же…

Traceback (most recent call last):
  File "C:\Documents and Settings\Администратор\Рабочий стол\123.py", line 54, in <module>
    text.append(canonize(docs[i]))
  File "C:\Documents and Settings\Администратор\Рабочий стол\123.py", line 26, in canonize
    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)]
  File "C:\Python27\lib\encodings\cp1251.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\xb8' in position 9: character maps to <undefined>
для того, чтобы программа работала на Вашем компьютере, отсылаю файл с самой программой(где локализована ошибка), с текстами и с библиотекой.

Прикреплённый файлы:
attachment все необходимое для программы.7z (388,2 KБ)

Офлайн

#5 Март 17, 2015 03:56:12

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9878
Репутация: +  853  -
Профиль   Отправить e-mail  

Проблема с "кракозябрами" при перекодировке

boyusha
x.encode('cp1251')
Сделай всё в utf-8. Стеммер с другой кодировкой не работает. И файлы там завершаются маковским способом - на \r, а надо сделать на \r\n, раз дело в винде происходит.



Отредактировано py.user.next (Март 17, 2015 03:57:16)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version