中央情报局关键词提取——Unicode码

Dataset

本文的任务是学习计算机在内存中如何存储一个值。本文的数据集sentences_cia.csv是中央情报局备忘录的一个摘录,描述了酷刑和其他秘密活动的细节。数据格式如下:

year,statement,,,

1997,”The FBI information included that al-Mairi’s brother “”traveled to Afghanistan in 1997-1998 to train in Bin - Ladencamps.”“”,,,

  • 整个csv文件就是一个长的字符串,我们之前讨论了字符串的应用,但一直不知道它们是如何被存储在一台电脑中。文件是存储在硬盘上的,硬盘通常是磁存储,将数据存储到磁条中。磁条只能存储两个值:up和down也就是高电压低电压,代表了计算机的0,1值。因此在存储我们的字符串前,我们需要将其转换为二进制,然后才能存储到磁条中。

Intro To Binary

  • 下面这段代码,首先b是一个二进制数据的字符串形式,然后将其转换为整数型二进制数再打印,同理打印了一个100的二进制数。
# Let‘s say a is a binary number.  In python, we have to store binary numbers as strings
# Trying to say b = 10 directly will assume base 10, so strings are needed
b = "10"

# We can convert b to a binary number from a string using the int function -- the optional second argument base is set to 2 (binary is base two)
print(int(b, 2))
‘‘‘
2
‘‘‘
base_10_100 = int("100", 2)
‘‘‘
base_10_100 :4
‘‘‘
  • 此处打印的结果人就是显示的十进制

Binary Addition

  • 二进制相加和十进制类似
b = "1"

# We‘ll add binary values using a binary_add function that was made just for this exercise
# It‘s not extremely important to know how it works right this second
def binary_add(a, b):
    return bin(int(a, 2) + int(b, 2))[2:]

c = binary_add(b, "1")

# We now see that c equals "10", which is exactly what happens in base 10 when we reach the highest possible digit.
print(c)
‘‘‘
10
‘‘‘
  • bin这个函数导致打印出来的形式是二进制,且由于前面会添加0b,因此打印的时候从第3个位置开始打印。

Converting Binary Values

  • 现在知道了利用int()函数可以将数据转换为其它进制。
def binary_add(a, b):
    return bin(int(a, 2) + int(b, 2))[2:]

# Start both at 0
a = 0
b = "0"

# Loop 10 times
for i in range(0, 10):
    # Add 1 to each
    a += 1
    b = binary_add(b, "1")

    # Check if they are equal
    print(int(b, 2) == a)
‘‘‘
True
True
True
True
True
True
True
True
True
True
‘‘‘
  • 上面这个例子表达了,无论是什么进制的数据,相加的量相同,他们不是一个进制但是任然数值是相等的。

Characters To Binary

字符串首先拆分成单个字符,然后存储为整型数据然后转换为二进制存储起来。

# We can use the ord() function to get the integer associated with an ascii character.
ord(‘a‘)

# Then we use the bin() function to convert to binary
# The bin function adds "0b" to the start of strings to indicate that they contain binary values
bin(ord(‘a‘))
print(bin(ord(‘a‘)))
‘‘‘
0b1100001
‘‘‘

# ? is the "last" ascii character -- it has the highest integer value of any ascii character
# This is because 255 is the highest value that can be represented with 8 binary digits
ord(‘?‘)
# As you can see, we get 8 1‘s, which shows that this is the highest possible 8 digit value
bin(ord(‘?‘))
print(bin(ord(‘?‘)))
‘‘‘
0b11111111
‘‘‘

# Why is this?  It‘s because a single binary digit is called a bit, and computers store values in sequences of bytes, which are 8 bits together.
# You might be more familiar with kilobytes or megabytes -- a kilobyte is 1000 bytes, and a megabyte is 1000 kilobytes.
# There are 256 different ascii symbols, because the largest amount of storage any single ascii character can take up is one byte.
binary_w = bin(ord("w"))
‘‘‘
str (<class ‘str‘>)
‘0b1110111‘
‘‘‘
  • 上面这段代码显示:字符类型数据总共是8位,字符数据需要转换为对应的ascii码,然后再转化为二进制数据存储起来,8位的二进制最多能存储255个字符。通过ord()函数可以获取一个字符的ascii码,而通过bin函数将数据转化为二进制,并且在数据的前面添加了0b表明这是个二进制字符串。

Intro To Unicode

我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000到11111111。 上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。 ASCII码一共规定了128个字符的编码,比如空格”SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。

  • Unicode

正如上一节所说,世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。 可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是Unicode,就像它的名字都表示的,这是一种所有符号的编码。 Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字”严”。具体的符号对应表,可以查询unicode.org,或者专门的汉字对应表。

  • Unicode的问题

需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。这里就有两个严重的问题,第一个问题是,如何才能区别Unicode和ASCII?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果Unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

  • UTF-8

UTF-8是Unicode的实现方式之一。UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。UTF-8的编码规则很简单,只有二条:

  • 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
  • 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

跟据上表,解读UTF-8编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

已知”严”的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此”严”的UTF-8编码需要三个字节,即格式是”1110xxxx 10xxxxxx 10xxxxxx”。然后,从”严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,”严”的UTF-8编码是”11100100 10111000 10100101”,转换成十六进制就是E4B8A5。可以看到”严”的Unicode码是4E25,UTF-8编码是E4B8A5,两者是不一样的。

# We can initialize unicode code points (the value for this code point is \u27F6, but you see it as a character because it is being automatically converted)
code_point = "→"

# This particular code point maps to a right arrow character
print(code_point)

# We can get the base 10 integer value of the code point with the ord function
print(ord(code_point))

# As you can see, this takes up a lot more than 1 byte
print(bin(ord(code_point)))
‘‘‘
→
10230
0b10011111110110
‘‘‘

Strings With Unicode

由于ascii 是Unicode的子集,因此在python3中,默认所有的字符串都是用Unicode,并且用utf-8编码。所以我们可以直接使用Unicode的码点和字符。

s1 = "café"
# The \u prefix means "the next 4 digits are a unicode code point"
# It doesn‘t change the value at all (the last character in the string below is \u00e9)
s2 = "café"

# These strings are the same, because code points are equal to their corresponding unicode character.
# \u00e9 and é are equivalent.
print(s1 == s2)
‘‘‘
True
‘‘‘

The Bytes Type

  • encode(“utf-8”)可以对字符串进行编码将其转换为bytes型数据。
# We can make a string with some unicode values
superman = "Clark Kent□"
# This tells python to encode the string superman into unicode using the utf-8 encoding
# We end up with a sequence of bytes instead of a string
superman_bytes = "Clark Kent?".encode("utf-8")
print(superman_bytes)
‘‘‘
b‘Clark Kent\xe2\x90\xa6‘
‘‘‘

batman = "Bruce Wayne□"
batman_bytes = batman.encode("utf-8")
print(batman_bytes)
‘‘‘
bytes (<class ‘bytes‘>)
b‘Bruce Wayne\xe2\x90\xa6‘
‘‘‘

Hexadecimal Intro

\u是unicode码的前缀,说明这代表一个unicode码。\x是十六进制的前缀,代表后面两个数字是16进制的。两个十六进制数等于8个二进制数。

# F is the highest single digit in hexadecimal (base 16)
# Its value is 15 in base 10
print(int("F", 16))

# A in base 16 has the value 10 in base 10
print(int("A", 16))

# Just like the earlier binary_add function, this adds two hex numbers
def hexadecimal_add(a, b):
    return hex(int(a, 16) + int(b, 16))[2:]

# When we add 1 to 9 in hexadecimal, it becomes "a"
value = "9"
value = hexadecimal_add(value, "1")
print(value)
hex_ea = hexadecimal_add("2", "ea")
‘‘‘
hex_ea :str (<class ‘str‘>)
‘ec‘
‘‘‘
hex_ef = hexadecimal_add("e", "f")
‘‘‘
hex_ef :str (<class ‘str‘>)
‘1d‘
‘‘‘
‘‘‘
15
10
a
‘‘‘

Hex To Binary

# One byte (8 bits) in hexadecimal (the value of the byte below is \xe2)
hex_byte = "a"

# Print the base 10 integer value for the hex byte
print(ord(hex_byte))

# This gives the exact same value -- remember than \x is just a prefix, and doesn‘t affect the value
print(int("e2", 16))

# Convert the base 10 integer to binary
print(bin(ord("a")))
binary_aa = bin(ord("a"))
‘‘‘
str (<class ‘str‘>)
‘0b10101010‘
‘‘‘
binary_ab = bin(ord("\xab"))
‘‘‘
str (<class ‘str‘>)
‘0b10101011‘
‘‘‘
‘‘‘
226
226
0b11100010
‘‘‘

Bytes And Strings

  • bytes和strings对象不可以混在一起,用encode(“utf-8”)会将一个strings对象转换为一个bytes对象,然后不能在其中插入strings对象,但是可以插入形如b”“这样的bytes对象
hulk_bytes = "Bruce Banner?".encode("utf-8")
print(type(hulk_bytes))
# We can‘t mix strings and bytes
# For instance, if we try to replace the unicode □ character as a string, it won‘t work, because that value has been encoded to bytes
try:
    hulk_bytes.replace("Banner", "")
except Exception:
    print("TypeError with replacement")

# We can create objects of the bytes datatype by putting a b in front of the quotation marks in a string
hulk_bytes = b"Bruce Banner"
# Now, instead of mixing strings and bytes, we can use the replace method with bytes objects instead
hulk_bytes.replace(b"Banner", b"")
thor_bytes = b"Thor"
‘‘‘
<class ‘bytes‘>
TypeError with replacement
‘‘‘

Decode Bytes To Strings

  • decode(“utf-8”)可以将bytes对象解码为strings对象。
# Make a bytes object with aquaman‘s secret identity
aquaman_bytes = b"Who knows?"

# Now, we can use the decode method, along with the encoding (utf-8) to turn it into a string.
aquaman = aquaman_bytes.decode("utf-8")

# We can print the value and type out to verify that it is a string.
print(aquaman)
print(type(aquaman))
‘‘‘
Who knows?
<class ‘str‘>
‘‘‘

Read In File Data

  • 到目前为止,对unicode有一定的了解了,现在开始处理数据了。
  • sentences_cia.csv”文件的第一行是列标签:[‘year’, ‘statement’, ”, ”, ”]
  • 第二行:[‘1997’, ‘The FBI information included that al-Mairi\’s brother “traveled to Afghanistan in 1997-1998 to train in Bin - Ladencamps.”’, ”, ”, ”]
# We can read our data in using csvreader
import csv
# When we open a file, we can specify the encoding that it‘s in.  In this case, utf-8
f = open("sentences_cia.csv", ‘r‘, encoding="utf-8")
csvreader = csv.reader(f)
sentences_cia = list(csvreader)

# The data is two columns
# First column is year, second is a sentence from a CIA report written that year
# Print the first column of the second row
print(sentences_cia[1][0])

# Print the second column of the second row
print(sentences_cia[1][1])
‘‘‘
1997
The FBI information included that al-Mairi‘s brother "traveled to Afghanistan in 1997-1998 to train in Bin - Ladencamps."
‘‘‘

Convert To A Dataframe

  • 将sentences_cia 转换为DataFrame对象,并且将legislators也同样处理。
import csv
# Let‘s read in the legislators data from a few missions ago
f = open("legislators.csv", ‘r‘, encoding="utf-8")
csvreader = csv.reader(f)
legislators = list(csvreader)

# Now, we can import pandas and use the DataFrame class to convert the list of lists to a dataframe
import pandas as pd

legislators_df = pd.DataFrame(legislators)

# As you can see, the first row is the headers, which we don‘t want (it‘s not actually data, it‘s just headers)
print(legislators_df.iloc[0,:])

# In order to remove the headers, we‘ll subset the df and pass them in separately
# This code removes the headers from legislators, and instead passes them into the columns argument
# The columns argument specifies column names
legislators_df = pd.DataFrame(legislators[1:], columns=legislators[0])
# We now have the right data in the first row, and the proper headers
print(legislators_df.iloc[0,:])

# The sentences_cia data from last screen is available.
sentences_cia_df = pd.DataFrame(sentences_cia[1:], columns=sentences_cia[0])
‘‘‘
0     last_name
1    first_name
2      birthday
3        gender
4          type
5         state
6         party
Name: 0, dtype: object
last_name                 Bassett
first_name                Richard
birthday               1745-04-02
gender                          M
type                          sen
state                          DE
party         Anti-Administration
Name: 0, dtype: object
‘‘‘

Clean Up Sentences

  • “statement”列是一个陈述句,必须对其进行处理然后才能进行分析。首先需要将strings中无关的符号剔除,我们只关心单词,数字和空格。所以我们先利用ord()查阅以上每个字符的整型码。good_characters列出了那些有用的码,保留这些字符,然后通过空格将其连接起来。
def clean_statement(row):
    # The integer codes for all the characters we want to keep
    good_characters = [48, 49, 50, 51, 52, 53, 54, 55, 56, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 32]
    statement = row["statement"]
    clean_statement_list = [s for s in statement if ord(s) in good_characters]
    # Join the list together, separated by "" (no space), which creates a string again
    return "".join(clean_statement_list)

sentences_cia["cleaned_statement"] = sentences_cia.apply(clean_statement, axis=1)

Tokenize Statements

  • 剔除掉无关单词后,需要将拆分单词,然后计算每个单词的频率,所以首先将所有的statement通过join函数连接在一起,在通过空格将其拆分为一个字符数组:
# We can use the .join() method on strings to join lists together.
# The string we use the method on will be used as the separator -- the character(s) between each string when they are joined.
combined_statements = " ".join(sentences_cia["cleaned_statement"])
statement_tokens = combined_statements.split(" ")
‘‘‘
list (<class ‘list‘>)
[‘The‘,
 ‘FBI‘,
 ‘information‘,
 ‘included‘,
 ‘that‘,
 ‘alMairis‘,
 ‘brother‘,
 ‘traveled‘,
 ...
‘‘‘

Filter The Tokens

  • 现在得到的是一个词袋形式,需要找到里面有用的单词的个数,但是在英语中最常见的单词是一些连接词,比如that or and等等,这些单词被称为停顿词,因此需要将这些单词过滤掉。但是为了简单起见,我们这里只是简单的将单词长度小于5的过滤掉:
# statement_tokens has been loaded in.
filtered_tokens = [s for s in statement_tokens if len(s) > 4]

Count The Tokens

  • 现在引入一个新的包collections,这个包里面有一个Counter函数,返回一个字典格式,键值为每个元素的频数。
from collections import Counter

# filtered_tokens has been loaded in
filtered_token_counts = Counter(filtered_tokens)
‘‘‘
Counter({‘interrogation‘: 391, ‘REDACTED‘: 375, ‘information‘: 375, ‘Zubaydah‘: 328, ‘Committee‘: 327, ...
‘‘‘
  • 然后计算其中最常见的3个单词:
common_tokens = filtered_token_counts.most_common(3)
‘‘‘
[(‘interrogation‘, 391), (‘REDACTED‘, 375), (‘information‘, 375)]
‘‘‘

Finding The Most Common Tokens By Year

# sentences_cia has been loaded in.
# It already has the cleaned_statement column.
from collections import Counter
def find_most_common_by_year(year, sentences_cia):
    data = sentences_cia[sentences_cia["year"] == year]
    combined_statement = " ".join(data["cleaned_statement"])
    statement_split = combined_statement.split(" ")
    counter = Counter([s for s in statement_split if len(s) > 4])
    return counter.most_common(2)

common_2000 = find_most_common_by_year("2000", sentences_cia)
‘‘‘
[(‘terrorist‘, 9), (‘Ahmad‘, 9)]
‘‘‘
common_2002 = find_most_common_by_year("2002", sentences_cia)
‘‘‘
[(‘interrogation‘, 275), (‘Zubaydah‘, 252)]
‘‘‘
common_2013 = find_most_common_by_year("2013", sentences_cia)
‘‘‘
[(‘Response‘, 196), (‘states‘, 111)]
‘‘‘
时间: 2024-10-12 07:44:01

中央情报局关键词提取——Unicode码的相关文章

Python调用百度接口(情感倾向分析)和讯飞接口(语音识别、关键词提取)处理音频文件

本示例的过程是: 1. 音频转文本 2. 利用文本获取情感倾向分析结果 3. 利用文本获取关键词提取 首先是讯飞的语音识别模块.在这里可以找到非实时语音转写的相关文档以及 Python 示例.我略作了改动,让它可以对不同人说话作区分,并且作了一些封装. 语音识别功能 weblfasr_python3_demo.py 文件: 1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 """ 4 讯飞非实时转写调用demo(语音识别)

Python中Unicode码和非Unicode码引起的错误与格式转换

1.1. 问题 Problem You need to deal with data that doesn't fit in the ASCII character set. 你需要处理不适合用ASCII字符集表示的数据. 1.2. 解决 Solution Unicode strings can be encoded in plain strings in a variety of ways, according to whichever encoding you choose: Unicode

python用正则表达式怎么查询unicode码字符

import re data = open('a.txt') fh = open('b.txt', 'w') """Search the string begining with '['""" p = re.compile(r'\s*[\u3010]') for each_d in data: if re.match('\s*3\d{4}', each_d): each_d = each_d.strip() print(each_d + ': '

查找字符对应Unicode码的十进制数字

//将字符转换为Unicode码中字符对应十进制数字 int byte0 = 'A' & 0xff;//byte0=65 参考文档:http://baike.baidu.com/view/2602518.htm  http://blog.idf.cn/2014/02/unicode-isnt-harmful-for-health-unicode-myths-debunked-and-encodings-demystified/

如何过滤 非中文的Unicode码

如何过滤 非中文的Unicode码,如 "我愿为你摘一朵鲜花 \u4e00-\u9fa5

将字符转换为unicode码

将字符转换为unicode码: /** * unicode转义字符 * @param ch * @param out */ public static void unicodeEscape(int ch, CharArr out) { out.write('\\'); out.write('u'); //字符ch向右移动12位之后,取最后一位 out.write(HEX_CHARS[ch>>>12]); //字符ch向右移动8位之后,取最后一位 out.write(HEX_CHARS[(

ascii码与unicode码的区别

ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统.它主要用于显示现代英语和其他西欧语言.它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646. ASCII 码使用指定的 7 位或 8 位二进制数组合来表示 128 或 256 种可能的字符.标准 ASCII 码也叫基础ASCII码,使用 7 位二进制数来表示所有的大写和小写字母,数字 0 到 9.标点符号, 以

java读取配置文件(properties)的时候,unicode码转utf-8

有时我们在读取properties结尾的配置文件的时候,如果配置文件中有中文,那么我们读取到的是unicode码的中文,需要我们在转换一下,代码如下 /** * 将配置文件中的Unicode 转 utf-8 汉字 * @param 原始字符串 * @return 转换后的格式的字符串 */ public static String unicodeToChina(String str) { Charset set = Charset.forName("UTF-16"); Pattern

idea properties文件unicode码问题

在git hub上下载了个工程.但是properties文件一直显示不了中文: # \u662F\u5426\u4F7F\u7528\u8FDC\u7A0B\u914D\u7F6E\u6587\u4EF6 # true(\u9ED8\u8BA4)\u4F1A\u4ECE\u8FDC\u7A0B\u83B7\u53D6\u914D\u7F6E false\u5219\u76F4\u63A5\u83B7\u53D6\u672C\u5730\u914D\u7F6E disconf.enable.rem